<!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>IMNB - SM2&#x7b97;&#x6cd5;&#x96c6;&#x6210;&#x6587;&#x6863;</title>
            <style>
/* From extension vscode.github */
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

.vscode-dark img[src$=\#gh-light-mode-only],
.vscode-light img[src$=\#gh-dark-mode-only],
.vscode-high-contrast:not(.vscode-high-contrast-light) img[src$=\#gh-light-mode-only],
.vscode-high-contrast-light img[src$=\#gh-dark-mode-only] {
	display: none;
}

/* From extension zhuangtongfa.material-theme */
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body {
  box-sizing: border-box;
  min-width: 200px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote {
  background-color: initial;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  color: initial;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body code {
  color: inherit;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre code {
  color: initial;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body code > div, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body code > div, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body code > div, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body code > div {
  background: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table td {
  border: 1px solid rgba(171, 178, 191, 0.5) !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body.showEditorSelection .code-active-line:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body.showEditorSelection .code-active-line:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body.showEditorSelection .code-active-line:before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body.showEditorSelection .code-active-line:before {
  border-left: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body.showEditorSelection .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body.showEditorSelection .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body.showEditorSelection .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body.showEditorSelection .code-line:hover:before {
  border-left: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body.showEditorSelection .code-line .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body.showEditorSelection .code-line .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body.showEditorSelection .code-line .code-line:hover:before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body.showEditorSelection .code-line .code-line:hover:before {
  border-left: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  margin-top: 16px;
  margin-bottom: 16px;
}

/* Generated from 'node_modules/github-markdown-css/github-markdown.css' */
@font-face {
  font-family: octicons-link;
  src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format("woff");
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body {
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  line-height: 1.5;
  color: rgb(171, 178, 191);
  line-height: 1.5;
  word-wrap: break-word;
  background: #282c34;
  padding-top: 20px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-c, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-c, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-c, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-c {
  color: #6a737d;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-c1, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-s .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-c1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-s .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-c1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-s .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-c1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-s .pl-v {
  color: #005cc5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-e, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-e, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-e, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-e, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-en {
  color: #6f42c1;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-smi, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-s .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-smi, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-s .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-smi, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-s .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-smi, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-s .pl-s1 {
  color: #24292e;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-ent, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-ent, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-ent, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-ent {
  color: #22863a;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-k, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-k, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-k, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-k {
  color: #d73a49;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-s, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-pds, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-s .pl-pse .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sr, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sr .pl-sre, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sr .pl-sra, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-s, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-pds, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-s .pl-pse .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sr .pl-sre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sr .pl-sra, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-s, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-pds, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-s .pl-pse .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sr .pl-sre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sr .pl-sra, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-s, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-pds, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-s .pl-pse .pl-s1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sr .pl-sre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sr .pl-sra {
  color: #032f62;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-smw, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-smw, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-smw, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-v, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-smw {
  color: #e36209;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-bu, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-bu, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-bu, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-bu {
  color: #b31d28;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-ii, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-ii, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-ii, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-ii {
  color: #fafbfc;
  background-color: #b31d28;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-c2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-c2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-c2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-c2 {
  color: #fafbfc;
  background-color: #d73a49;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-c2::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-c2::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-c2::before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-c2::before {
  content: "^M";
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sr .pl-cce, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sr .pl-cce {
  font-weight: bold;
  color: #22863a;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-ml, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-ml, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-ml, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-ml {
  color: #735c0f;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mh, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mh .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-ms, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mh, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mh .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-ms, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mh, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mh .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-ms, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mh, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mh .pl-en, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-ms {
  font-weight: bold;
  color: #005cc5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mi, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mi, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mi, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mi {
  font-style: italic;
  color: #24292e;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mb, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mb, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mb, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mb {
  font-weight: bold;
  color: #24292e;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-md, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-md, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-md, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-md {
  color: #b31d28;
  background-color: #ffeef0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mi1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mi1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mi1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mi1 {
  color: #22863a;
  background-color: #f0fff4;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mc, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mc, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mc, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mc {
  color: #e36209;
  background-color: #ffebda;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mi2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mi2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mi2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mi2 {
  color: #f6f8fa;
  background-color: #005cc5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-mdr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-mdr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-mdr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-mdr {
  font-weight: bold;
  color: #6f42c1;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-ba, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-ba, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-ba, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-ba {
  color: #586069;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-sg, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-sg, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-sg, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-sg {
  color: #959da5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-corl, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-corl, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-corl, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-corl {
  text-decoration: underline;
  color: #032f62;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .octicon {
  display: inline-block;
  vertical-align: text-top;
  fill: currentColor;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a {
  background-color: transparent;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a:active, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a:active, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a:active, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a:active, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a:hover {
  outline-width: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body strong {
  font-weight: inherit;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body strong {
  font-weight: bolder;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1 {
  margin: 0.67em 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body img {
  border-style: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body input {
  font: inherit;
  margin: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body input {
  overflow: visible;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body [type=checkbox], .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body [type=checkbox], .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body [type=checkbox], .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body [type=checkbox] {
  box-sizing: border-box;
  padding: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body *, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body *, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body *, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body * {
  box-sizing: border-box;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body input, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body input {
  font-family: inherit;
  line-height: inherit;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a {
  color: #528bff;
  text-decoration: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a:hover, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a:hover {
  text-decoration: underline;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body strong, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body strong {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr {
  height: 0;
  margin: 15px 0;
  overflow: hidden;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #dfe2e5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr::before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr::before {
  display: table;
  content: "";
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr::after, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr::after, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr::after, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr::after {
  display: table;
  clear: both;
  content: "";
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table {
  border-spacing: 0;
  border-collapse: collapse;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body td, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body th, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body td, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body th, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body td, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body th, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body td, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body th {
  padding: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6 {
  margin-top: 0;
  margin-bottom: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6 {
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body p {
  margin-top: 0;
  margin-bottom: 10px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote {
  margin: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol {
  padding-left: 0;
  margin-top: 0;
  margin-bottom: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul ol {
  list-style-type: lower-roman;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol ol ol {
  list-style-type: lower-alpha;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dd, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dd, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dd, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dd {
  margin-left: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  margin-top: 0;
  margin-bottom: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .octicon, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .octicon {
  vertical-align: text-bottom;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-0, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-0, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-0, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-0 {
  padding-left: 0 !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-1 {
  padding-left: 4px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-2 {
  padding-left: 8px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-3, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-3, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-3, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-3 {
  padding-left: 16px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-4, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-4, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-4, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-4 {
  padding-left: 24px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-5, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-5, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-5, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-5 {
  padding-left: 32px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .pl-6, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .pl-6, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .pl-6, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .pl-6 {
  padding-left: 40px !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body::before, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body::before, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body::before {
  display: table;
  content: "";
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body::after, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body::after, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body::after, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body::after {
  display: table;
  clear: both;
  content: "";
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body > *:first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body > *:first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body > *:first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body > *:first-child {
  margin-top: 0 !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body > *:last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body > *:last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body > *:last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body > *:last-child {
  margin-bottom: 0 !important;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body a:not([href]), .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body a:not([href]), .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body a:not([href]), .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body a:not([href]) {
  color: inherit;
  text-decoration: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .anchor {
  float: left;
  padding-right: 4px;
  margin-left: -20px;
  line-height: 1;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .anchor:focus, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .anchor:focus, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .anchor:focus, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .anchor:focus {
  outline: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body p, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  margin-top: 0;
  margin-bottom: 16px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr {
  height: 0.25em;
  padding: 0;
  margin: 24px 0;
  background-color: #e1e4e8;
  border: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote {
  /* padding: 0 1em;
  color: #6a737d;
  border-left: 0.25em solid #dfe2e5; */
  padding: 8.5px 17px;
  margin: 1.5em 0;
  color: #7c879c;
  border-color: #4b5362;
  border-width: 4px;
  border-left: 5px solid #4b5362;
  background: transparent;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote > :first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote > :first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote > :first-child, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote > :first-child {
  margin-top: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body blockquote > :last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body blockquote > :last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body blockquote > :last-child, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body blockquote > :last-child {
  margin-bottom: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body kbd {
  display: inline-block;
  padding: 3px 5px;
  line-height: 10px;
  color: #444d56;
  vertical-align: middle;
  background-color: #fafbfc;
  border: solid 1px #c6cbd1;
  border-bottom-color: #959da5;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #959da5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6 {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: rgb(240, 240, 240);
  border-bottom: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5 .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6 .octicon-link {
  color: #1b1f23;
  vertical-align: middle;
  visibility: hidden;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5:hover .anchor, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6:hover .anchor {
  text-decoration: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h3:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h4:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h5:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h3:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h4:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h5:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h3:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h4:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h5:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h3:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h4:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h5:hover .anchor .octicon-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6:hover .anchor .octicon-link {
  visibility: visible;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h1, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h1 {
  padding-bottom: 0.3em;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h2, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h2 {
  padding-bottom: 0.3em;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body h6, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body h6 {
  color: #6a737d;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol {
  padding-left: 2em;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body ol ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body ol ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul ul, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body ol ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul ul, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ul ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol ol, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body ol ul {
  margin-top: 0;
  margin-bottom: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body li, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body li, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body li, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body li {
  word-wrap: break-all;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body li > p, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body li > p, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body li > p, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body li > p {
  margin-top: 16px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body li + li, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body li + li, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body li + li, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body li + li {
  margin-top: 0.25em;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dl, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dl {
  padding: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dl dt, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dl dt, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dl dt, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dl dt {
  padding: 0;
  margin-top: 16px;
  font-style: italic;
  font-weight: 600;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body dl dd, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body dl dd, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body dl dd, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body dl dd {
  padding: 0 16px;
  margin-bottom: 16px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table {
  display: block;
  width: 100%;
  overflow: auto;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table th {
  font-weight: 700;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body table td, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table th, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body table td {
  padding: 6px 13px;
  /* border: 1px solid #dfe2e5; */
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body img, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body img {
  max-width: 100%;
  box-sizing: content-box;
  display: inline-block;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body img[align=right], .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body img[align=right], .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body img[align=right], .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body img[align=right] {
  padding-left: 20px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body img[align=left], .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body img[align=left], .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body img[align=left], .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body img[align=left] {
  padding-right: 20px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body code, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body code {
  padding: 0.2em 0.4em;
  margin: 0;
  background-color: #3a3f4b;
  border-radius: 3px;
  color: white;
  margin: 0 1px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  word-wrap: normal;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre > code, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre > code, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre > code, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre > code {
  padding: 0;
  margin: 0;
  word-break: normal;
  white-space: pre;
  background: transparent;
  border: 0;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .highlight, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .highlight, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .highlight, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .highlight {
  margin-bottom: 16px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .highlight pre {
  margin-bottom: 0;
  word-break: normal;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .highlight pre, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre {
  padding: 16px;
  overflow: auto;
  line-height: 1.45;
  /* background-color: #f6f8fa; */
  border-radius: 3px;
  background-color: #31363f;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body pre code, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body pre code {
  display: inline;
  max-width: auto;
  padding: 0;
  margin: 0;
  overflow: visible;
  line-height: inherit;
  word-wrap: normal;
  background-color: transparent;
  border: 0;
  color: rgb(171, 178, 191);
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .full-commit .btn-outline:not(:disabled):hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .full-commit .btn-outline:not(:disabled):hover, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .full-commit .btn-outline:not(:disabled):hover, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .full-commit .btn-outline:not(:disabled):hover {
  color: #005cc5;
  border-color: #005cc5;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body kbd, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body kbd {
  display: inline-block;
  padding: 3px 5px;
  line-height: 10px;
  color: #444d56;
  vertical-align: middle;
  background-color: #fafbfc;
  border: solid 1px #d1d5da;
  border-bottom-color: #c6cbd1;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #c6cbd1;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body :checked + .radio-label, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body :checked + .radio-label, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body :checked + .radio-label, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body :checked + .radio-label {
  position: relative;
  z-index: 1;
  border-color: #0366d6;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .task-list-item {
  list-style-type: none;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .task-list-item + .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .task-list-item + .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .task-list-item + .task-list-item, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .task-list-item + .task-list-item {
  margin-top: 3px;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body .task-list-item input, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body .task-list-item input, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body .task-list-item input, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body .task-list-item input {
  margin: 0 0.2em 0.25em -1.6em;
  vertical-align: middle;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"].vscode-body hr, .vscode-dark[data-vscode-theme-name="One Dark Pro"].vscode-body hr {
  border-bottom-color: #eee;
}

/*

Atom One Dark by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax

base:    #282c34
mono-1:  #abb2bf
mono-2:  #818896
mono-3:  #5c6370
hue-1:   #56b6c2
hue-2:   #61aeee
hue-3:   #c678dd
hue-4:   #98c379
hue-5:   #e06c75
hue-5-2: #be5046
hue-6:   #d19a66
hue-6-2: #e6c07b

*/
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs {
  display: block;
  overflow-x: auto;
  padding: 0.5em;
  color: #abb2bf;
  background: #282c34;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-comment,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-quote, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-comment,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-quote, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-comment,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-quote, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-comment,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-quote {
  color: #5c6370;
  font-style: italic;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-doctag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-keyword,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-formula, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-doctag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-keyword,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-formula, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-doctag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-keyword,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-formula, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-doctag,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-keyword,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-formula {
  color: #c678dd;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-section,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-name,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-selector-tag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-deletion,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-subst, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-section,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-name,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-selector-tag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-deletion,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-subst, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-section,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-name,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-selector-tag,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-deletion,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-subst, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-section,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-name,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-selector-tag,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-deletion,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-subst {
  color: #e06c75;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-literal, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-literal, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-literal, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-literal {
  color: #56b6c2;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-string,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-regexp,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-addition,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-attribute,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-meta-string, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-string,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-regexp,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-addition,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-attribute,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-meta-string, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-string,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-regexp,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-addition,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-attribute,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-meta-string, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-string,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-regexp,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-addition,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-attribute,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-meta-string {
  color: #98c379;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-built_in,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-class .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-built_in,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-class .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-built_in,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-class .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-built_in,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-class .hljs-title {
  color: #e6c07b;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-template-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-type,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-selector-class,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-selector-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-selector-pseudo,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-number, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-template-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-type,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-selector-class,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-selector-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-selector-pseudo,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-number, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-template-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-type,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-selector-class,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-selector-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-selector-pseudo,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-number, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-template-variable,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-type,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-selector-class,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-selector-attr,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-selector-pseudo,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-number {
  color: #d19a66;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-symbol,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-bullet,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-link,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-meta,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-selector-id,
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-symbol,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-bullet,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-link,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-meta,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-selector-id,
.vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-symbol,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-bullet,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-link,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-meta,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-selector-id,
.vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-title, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-symbol,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-bullet,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-link,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-meta,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-selector-id,
.vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-title {
  color: #61aeee;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-emphasis, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-emphasis, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-emphasis, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-emphasis {
  font-style: italic;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-strong, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-strong, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-strong {
  font-weight: bold;
}
.vscode-dark[data-vscode-theme-name="One Dark Pro Mix"] .hljs-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Flat"] .hljs-link, .vscode-dark[data-vscode-theme-name="One Dark Pro Darker"] .hljs-link, .vscode-dark[data-vscode-theme-name="One Dark Pro"] .hljs-link {
  text-decoration: underline;
}

</style>
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.css">
<link href="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;
                font-size: 14px;
                line-height: 1.6;
            }
        </style>
        <style>
.task-list-item {
    list-style-type: none;
}

.task-list-item-checkbox {
    margin-left: -20px;
    vertical-align: middle;
    pointer-events: none;
}
</style>
<style>
:root {
  --color-note: #0969da;
  --color-tip: #1a7f37;
  --color-warning: #9a6700;
  --color-severe: #bc4c00;
  --color-caution: #d1242f;
  --color-important: #8250df;
}

</style>
<style>
@media (prefers-color-scheme: dark) {
  :root {
    --color-note: #2f81f7;
    --color-tip: #3fb950;
    --color-warning: #d29922;
    --color-severe: #db6d28;
    --color-caution: #f85149;
    --color-important: #a371f7;
  }
}

</style>
<style>
.markdown-alert {
  padding: 0.5rem 1rem;
  margin-bottom: 16px;
  color: inherit;
  border-left: .25em solid #888;
}

.markdown-alert>:first-child {
  margin-top: 0
}

.markdown-alert>:last-child {
  margin-bottom: 0
}

.markdown-alert .markdown-alert-title {
  display: flex;
  font-weight: 500;
  align-items: center;
  line-height: 1
}

.markdown-alert .markdown-alert-title .octicon {
  margin-right: 0.5rem;
  display: inline-block;
  overflow: visible !important;
  vertical-align: text-bottom;
  fill: currentColor;
}

.markdown-alert.markdown-alert-note {
  border-left-color: var(--color-note);
}

.markdown-alert.markdown-alert-note .markdown-alert-title {
  color: var(--color-note);
}

.markdown-alert.markdown-alert-important {
  border-left-color: var(--color-important);
}

.markdown-alert.markdown-alert-important .markdown-alert-title {
  color: var(--color-important);
}

.markdown-alert.markdown-alert-warning {
  border-left-color: var(--color-warning);
}

.markdown-alert.markdown-alert-warning .markdown-alert-title {
  color: var(--color-warning);
}

.markdown-alert.markdown-alert-tip {
  border-left-color: var(--color-tip);
}

.markdown-alert.markdown-alert-tip .markdown-alert-title {
  color: var(--color-tip);
}

.markdown-alert.markdown-alert-caution {
  border-left-color: var(--color-caution);
}

.markdown-alert.markdown-alert-caution .markdown-alert-title {
  color: var(--color-caution);
}

</style>
        
        </head>
        <body class="vscode-body vscode-light">
            <style>
    img {
        width: 75%;
    }
</style>
<h1 id="imnb---sm2算法集成文档">IMNB - SM2算法集成文档</h1>
<h2 id="1-相关标准">1. 相关标准</h2>
<p>本小组根据国家推荐标准</p>
<ul>
<li>GB/T 32198.1 - 2016 《信息安全技术 SM2椭圆曲线公钥密码算法 第1部分：总则》</li>
<li>GB/T 32198.2 - 2016 《信息安全技术 SM2椭圆曲线公钥密码算法 第2部分：数字签名算法》</li>
<li>GB_T 32918.4 — 2016 《信息安全技术 SM2椭圆曲线公钥密码算法 第4部分：公钥加密算法》</li>
<li>GB/T 32198.5 - 2017 《信息安全技术 SM2椭圆曲线公钥密码算法 第5部分：参数定义》</li>
<li>GB/T 32905 - 2016 《信息安全技术 SM3密码杂凑算法》</li>
</ul>
<p>对SM2算法的签名功能和验签功能、加密和解密功能进行实现。</p>
<h2 id="2-代码结构">2. 代码结构</h2>
<p><code>BSW/Crypto/SM2</code></p>
<ul>
<li><code>sm2_operation.c</code>，<code>sm2_operation.h</code>。定义了基本的运算模块。包括基本大数加法运算、减法运算、乘法运算；有限域<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">F_{p}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9694em;vertical-align:-0.2861em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span>加法运算、减法运算、快速模乘运算、快速模逆运算、快速模幂运算；Montgomery模乘算法，Montgomery模约简算法和Montgomery模幂运算。</li>
<li><code>sm2_ec.c</code>，<code>sm2_ec.h</code>。定义了<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">F_{p}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9694em;vertical-align:-0.2861em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span>下椭圆曲线的有限域运算。包括仿射坐标和Jacobian加重射影坐标系中点和椭圆曲线的定义，点加运算、倍点运算、坐标系的转化操作等。</li>
<li><code>sm2.c</code>，<code>sm2.h</code>。定义了SM2签名和验签的封装函数和中间操作。</li>
<li><code>sm3.c</code>，<code>sm3.h</code>。定义了SM3密码杂凑算法。</li>
<li><code>sm2_rand.c</code>，<code>sm2_rand.h</code>。定义了大数随机数生成函数。</li>
<li><code>sm2_5_naf.c</code>, <code>sm2_5_naf.h</code>。定义了5-NAF（5 Non-Adjacent Form）优化技术相关函数，用于优化SM2椭圆曲线算法的标量乘法运算（点乘）以提高标量乘法效率。</li>
<li><code>sm2_safegcd.c</code>, <code>sm2_safegcd.h</code>。实现了通过扩展欧几里得算法进行大数求模逆的运算。相较于早前的基于费马小定理实现模逆有一定性能提升。同时存在一些关键优化如下：
<ul>
<li>常量时间实现。所实现的<code>sm2_modinv64</code>设计位常量时间操作，以避免侧信道攻击。由于扩展欧几里得算法对于不同长度输入存在处理时间上的差别，该算法有助于解决攻击者通过测量时间来推算秘密信息的问题。</li>
</ul>
</li>
<li><code>sm2_pre_comp_G.c</code>。该函数存储一个与计算的基点倍乘表，所存储的数据为基点根据7bit为窗口单位预计算的倍点的仿射坐标值。用于加速椭圆曲线标量乘法运算。</li>
<li><code>sm2_pre_comp_G_3_window.c</code>;<br>
<code>sm2_pre_comp_G_5_window.c</code>;<br>
<code>sm2_pre_comp_G_7_window.c</code>。不同窗口大小的基点倍点预计算表实现。</li>
<li><code>sm2_5_jsf.c</code>, <code>sm2_5_jsf.h</code>: 用于加速倍点运算的JSF-5算法实现。</li>
<li><code>sm2_enc.c</code>：定义了SM2加密解密函数。</li>
</ul>
<p><code>BSW/Crypto</code></p>
<ul>
<li>
<p><code>Crypto.c</code>。添加了对所实现的SM2签名、验签、密钥对生成与计算以及SM3散列计算函数的调用逻辑</p>
</li>
<li>
<p><code>BSW/Config/Os_UserInf.c</code>。用于配置Task</p>
</li>
</ul>
<p><code>ASW</code></p>
<ul>
<li><code>main.c</code>。主函数，用于调用示例程序或初始化系统</li>
</ul>
<h2 id="3-主要功能实现">3. 主要功能实现</h2>
<p>如下是一部分关键模块的实现。</p>
<h3 id="31-大数运算-sm2_operationc">3.1 大数运算 <code>sm2_operation.c</code></h3>
<p>针对大数运算，我们实现小端法存储256bit和512bit大数类型。包括两个基本类型：</p>
<ul>
<li><code>typedef uint32_t sm2_uint256_t[8]</code></li>
<li><code>typedef uint32_t sm2_uint512_t[16]</code></li>
</ul>
<p>对于基本运算，有如下关键函数：</p>
<table>
<thead>
<tr>
<th>函数名称</th>
<th style="text-align:left">解释</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sm2_set_zero</code></td>
<td style="text-align:left">用于将32字节大数清零</td>
</tr>
<tr>
<td><code>sm2_set_one</code></td>
<td style="text-align:left">用于将32字节大数设为1</td>
</tr>
<tr>
<td><code>sm2_compare</code></td>
<td style="text-align:left">接受两个32字节大数并进行比较，返回三种比较结果:<br/><code>SM2_COMPARE_LT</code>: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>&lt;</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a \lt b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span></span></span></span><br/><code>SM2_COMPARE_GT</code>: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>&gt;</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a \gt b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span></span></span></span><br/><code>SM2_COMPARE_EQ</code>: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a = b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span></span></span></span></td>
</tr>
<tr>
<td><code>sm2_compare_overflow</code></td>
<td style="text-align:left">同sm2_compare功能相同，但可以处理64字节大数</td>
</tr>
<tr>
<td><code>sm2_add</code></td>
<td style="text-align:left">执行两个256位数值的加法运算，处理进位，并返回最终的进位值。</td>
</tr>
<tr>
<td><code>sm2_512_add</code></td>
<td style="text-align:left">执行两个512位数值的加法运算，处理进位，并返回最终的进位值。</td>
</tr>
<tr>
<td><code>sm2_sub</code></td>
<td style="text-align:left">执行两个256位数值的减法运算，处理借位，并返回最终的借位值。</td>
</tr>
<tr>
<td><code>sm2_overflow_sub</code></td>
<td style="text-align:left">执行两个512位数值的减法运算，处理借位，并返回最终的借位值。</td>
</tr>
<tr>
<td><code>sm2_mul</code></td>
<td style="text-align:left">执行两个256位数值的乘法运算，结果存储在512位数值中。</td>
</tr>
<tr>
<td><code>sm2_mod_add</code></td>
<td style="text-align:left">执行两个256位数值的加法并进行模P运算，确保结果在模数范围内。</td>
</tr>
<tr>
<td><code>sm2_mod_sub</code></td>
<td style="text-align:left">执行两个256位数值的减法并进行模P运算，确保结果在模数范围内。</td>
</tr>
<tr>
<td><code>sm2_mod_neg</code></td>
<td style="text-align:left">计算给定256位数值的模P负值，即<code>result=P-a</code>。</td>
</tr>
<tr>
<td><code>sm2_mod_mul</code></td>
<td style="text-align:left">计算两个256位数值的模P乘积，结果通过快速模约简映射到256位。</td>
</tr>
<tr>
<td><code>sm2_mod_sqr</code></td>
<td style="text-align:left">计算一个256位数值的模P平方，调用<code>sm2_mod_mul</code>进行模乘运算。</td>
</tr>
<tr>
<td><code>sm2_mod_k_mul</code></td>
<td style="text-align:left">计算32位常数与256位数值的模P乘积。</td>
</tr>
<tr>
<td><code>sm2_fast_mod_reduction</code></td>
<td style="text-align:left">执行快速模约简运算，将一个512位的大整数按SM2算法的模约简方法约简为256位数值。</td>
</tr>
<tr>
<td><code>sm2_fast_mod_inverse</code></td>
<td style="text-align:left">计算给定256位数值在模P下的模逆元，使用一系列平方和乘法运算。</td>
</tr>
<tr>
<td><code>sm2_modn_add</code></td>
<td style="text-align:left">计算两个256位数值的模N加法，即<code>(a+b)modN</code>，并处理溢出情况。</td>
</tr>
<tr>
<td><code>sm2_modn_sub</code></td>
<td style="text-align:left">计算两个256位数值的模N减法，即<code>(a-b)modN</code>，并处理下溢情况。</td>
</tr>
<tr>
<td><code>sm2_modn_neg</code></td>
<td style="text-align:left">计算一个256位数值的模N负值，即<code>(-a)modN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_mul</code></td>
<td style="text-align:left">执行在模N下的蒙哥马利乘法，即<code>(a*b)modN</code>，使用蒙哥马利算法优化运算。</td>
</tr>
<tr>
<td><code>sm2_modn_mul</code></td>
<td style="text-align:left">执行模N乘法运算，通过转换到蒙哥马利域进行乘法运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_sqr</code></td>
<td style="text-align:left">执行在模N下的蒙哥马利平方运算，即<code>(a*a)modN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_sqr</code></td>
<td style="text-align:left">执行模N平方运算，通过转换到蒙哥马利域进行平方运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_exp</code></td>
<td style="text-align:left">执行在模N下的蒙哥马利指数运算，即<code>a^bmodN</code>，使用蒙哥马利方法进行优化。</td>
</tr>
<tr>
<td><code>sm2_modn_exp</code></td>
<td style="text-align:left">执行模N指数运算，通过转换到蒙哥马利域进行指数运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_inverse</code></td>
<td style="text-align:left">执行在模N下的蒙哥马利反元素运算，计算给定数值的模N逆元。</td>
</tr>
<tr>
<td><code>sm2_modn_inverse</code></td>
<td style="text-align:left">执行模N逆元素运算，通过转换到蒙哥马利域计算逆元后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_from_mont</code></td>
<td style="text-align:left">将数值从蒙哥马利表示转换回常规表示。</td>
</tr>
<tr>
<td><code>sm2_modn_to_mont</code></td>
<td style="text-align:left">将数值从常规表示转换为蒙哥马利表示。</td>
</tr>
<tr>
<td><code>sm2_modp_mont_mul</code></td>
<td style="text-align:left">执行在模P下的蒙哥马利乘法，即<code>(a*b)modP</code>，使用蒙哥马利算法优化运算。</td>
</tr>
<tr>
<td><code>sm2_modp_to_mont</code></td>
<td style="text-align:left">将数值从常规表示转换为模P的蒙哥马利表示。</td>
</tr>
<tr>
<td><code>sm2_modp_from_mont</code></td>
<td style="text-align:left">将数值从模P的蒙哥马利表示转换回常规表示。</td>
</tr>
<tr>
<td><code>sm2_mod_mul1</code></td>
<td style="text-align:left">执行模P乘法运算，通过转换到蒙哥马利域进行乘法运算后转换回常规域。</td>
</tr>
<tr>
<td><code>print_256</code></td>
<td style="text-align:left">按小端法打印256位数值的值。</td>
</tr>
<tr>
<td><code>print_256_64</code></td>
<td style="text-align:left">按小端法打印256位数值（使用64位表示）的值。</td>
</tr>
<tr>
<td><code>print_512</code></td>
<td style="text-align:left">按小端法打印512位数值的值。</td>
</tr>
<tr>
<td><code>sm2_print</code></td>
<td style="text-align:left">按照指定格式打印256位数值，并带有标签。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_inverse</code></td>
<td style="text-align:left">执行模N蒙哥马利反元素运算，计算给定数值的模N逆元。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_exp</code></td>
<td style="text-align:left">执行模N蒙哥马利指数运算，计算<code>a^bmodN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_sqr</code></td>
<td style="text-align:left">执行模N蒙哥马利平方运算，计算<code>(a*a)modN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_mul</code></td>
<td style="text-align:left">执行模N蒙哥马利乘法运算，计算<code>(a*b)modN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_to_mont</code></td>
<td style="text-align:left">将数值从常规表示转换为蒙哥马利表示。</td>
</tr>
<tr>
<td><code>sm2_modn_from_mont</code></td>
<td style="text-align:left">将数值从蒙哥马利表示转换回常规表示。</td>
</tr>
<tr>
<td><code>sm2_modn_inverse</code></td>
<td style="text-align:left">执行模N逆元素运算，通过转换到蒙哥马利域计算逆元后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_inverse</code></td>
<td style="text-align:left">执行模N蒙哥马利反元素运算，计算给定数值的模N逆元。</td>
</tr>
<tr>
<td><code>sm2_modn_exp</code></td>
<td style="text-align:left">执行模N指数运算，通过转换到蒙哥马利域进行指数运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mul</code></td>
<td style="text-align:left">执行模N乘法运算，通过转换到蒙哥马利域进行乘法运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_mul</code></td>
<td style="text-align:left">执行模N蒙哥马利乘法运算，计算<code>(a*b)modN</code>。</td>
</tr>
<tr>
<td><code>sm2_modn_sqr</code></td>
<td style="text-align:left">执行模N平方运算，通过转换到蒙哥马利域进行平方运算后转换回常规域。</td>
</tr>
<tr>
<td><code>sm2_modn_mont_sqr</code></td>
<td style="text-align:left">执行模N蒙哥马利平方运算，计算<code>(a*a)modN</code>。</td>
</tr>
</tbody>
</table>
<h3 id="32-椭圆曲线有限域计算-sm2_ecc">3.2 椭圆曲线有限域计算 <code>sm2_ec.c</code></h3>
<table>
<thead>
<tr>
<th>函数名称</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sm2_set_point_infi</code></td>
<td>设置Jacobian加重射影坐标系点为无穷远点<code>(1,1,0)</code>。</td>
</tr>
<tr>
<td><code>sm2_set_jacobian_point</code></td>
<td>将仿射坐标<code>(x,y)</code>转换为Jacobian坐标<code>(X,Y,Z)</code>，其中<code>X=x</code>，<code>Y=y</code>，<code>Z=1</code>，表示标准化的Jacobian坐标。</td>
</tr>
<tr>
<td><code>sm2_set_jacobian_point_from_std</code></td>
<td>将标准仿射坐标点<code>SM2_Point</code>转换为Jacobian坐标点<code>SM2_Jacobian_Point</code>，设置<code>Z=1</code>。</td>
</tr>
<tr>
<td><code>sm2_get_std_point</code></td>
<td>将Jacobian坐标点转换为标准仿射坐标点。首先通过<code>sm2_get_affine_point</code>获取仿射坐标，然后将<code>x</code>和<code>y</code>坐标赋值给标准坐标点<code>result</code>。</td>
</tr>
<tr>
<td><code>sm2_get_affine_point</code></td>
<td>将Jacobian坐标点<code>p</code>转换为仿射坐标。如果<code>Z=0</code>（无穷远点），则直接复制点；否则，计算<code>X/Z²</code>和<code>Y/Z³</code>得到仿射坐标。</td>
</tr>
<tr>
<td><code>sm2_point_compare</code></td>
<td>比较两个Jacobian坐标点<code>a</code>和<code>b</code>是否相等。通过将它们转换为仿射坐标后比较<code>x</code>和<code>y</code>坐标是否相同。</td>
</tr>
<tr>
<td><code>sm2_point_copy</code></td>
<td>将一个Jacobian坐标点<code>p</code>复制到另一个Jacobian坐标点<code>result</code>。</td>
</tr>
<tr>
<td><code>sm2_is_point_inverse</code></td>
<td>检查两个Jacobian坐标点<code>p1</code>和<code>p2</code>是否互为逆点，即<code>p1=-p2</code>。如果是，则返回<code>1</code>，否则返回<code>0</code>。</td>
</tr>
<tr>
<td><code>sm2_jacobian_point_equal</code></td>
<td>比较两个Jacobian坐标点<code>p1</code>和<code>p2</code>是否相等。通过验证<code>X1*Z2²==X2*Z1²</code>和<code>Y1*Z2³==Y2*Z1³</code>来确定相等性。</td>
</tr>
<tr>
<td><code>sm2_point_double</code></td>
<td>对Jacobian坐标点<code>p</code>进行倍点操作，计算<code>result=2*p</code>。使用Jacobian坐标系中的倍点公式进行高效计算。</td>
</tr>
<tr>
<td><code>sm2_jacobian_point_add</code></td>
<td>在Jacobian坐标系中执行椭圆曲线点加法<code>result=p1+p2</code>。处理特殊情况如无穷远点、互为逆点和相等点，并使用标准Jacobian加法公式进行一般情况的点加法。</td>
</tr>
<tr>
<td><code>sm2_jacobian_point_neg</code></td>
<td>计算Jacobian坐标点<code>p</code>的负点<code>result=-p</code>，即<code>result=(X,-Y,Z)</code>。</td>
</tr>
<tr>
<td><code>sm2_point_neg_affine</code></td>
<td>计算仿射坐标点<code>p</code>的负点<code>result=-p</code>，即<code>result=(X,-Y)</code>。</td>
</tr>
<tr>
<td><code>sm2_z256_get_booth</code></td>
<td>获取256位标量<code>k</code>的Booth编码，用于窗口化的标量乘法算法。根据指定的窗口大小提取对应位置的位，并进行编码转换。</td>
</tr>
<tr>
<td><code>sm2_z256_point_copy_affine</code></td>
<td>将仿射坐标点<code>SM2_Point</code>复制到Jacobian坐标点<code>SM2_Jacobian_Point</code>，设置<code>Z=1</code>。</td>
</tr>
<tr>
<td><code>sm2_point_add_affine</code></td>
<td>在Jacobian坐标系中将Jacobian点<code>P</code>与仿射点<code>Q</code>相加，结果存储在<code>R</code>中。</td>
</tr>
<tr>
<td><code>sm2_point_sub_affine</code></td>
<td>在Jacobian坐标系中将Jacobian点<code>P</code>减去仿射点<code>Q</code>，结果存储在<code>R</code>中。</td>
</tr>
<tr>
<td><code>sm2_point_mul_generator</code></td>
<td>计算基点<code>G</code>的标量乘法<code>R=k*G</code>，使用预计算的点表和Booth算法优化计算过程。</td>
</tr>
<tr>
<td><code>sm2_point_on_curve</code></td>
<td>检查Jacobian坐标点<code>a</code>是否满足SM2椭圆曲线方程<code>y²=x³+a*x+b</code>。如果满足，返回<code>1</code>，否则返回<code>0</code>。</td>
</tr>
<tr>
<td><code>print_point</code></td>
<td>打印Jacobian坐标点<code>p</code>的<code>x</code>、<code>y</code>、<code>z</code>坐标值。如果指针<code>p</code>为空，则打印&quot;NULL&quot;。</td>
</tr>
<tr>
<td><code>print_std_point</code></td>
<td>打印标准仿射坐标点<code>p</code>的<code>x</code>和<code>y</code>坐标值。如果指针<code>p</code>为空，则打印&quot;NULL&quot;。</td>
</tr>
</tbody>
</table>
<h3 id="33-sm2签名验签操作sm2c">3.3 SM2签名验签操作<code>sm2.c</code></h3>
<table>
<thead>
<tr>
<th>函数名称</th>
<th style="text-align:left">解释</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sm2_rand</code></td>
<td style="text-align:left">产生一个位于指定区间<code>[low,high)</code>内的256位随机大数<code>k</code>。</td>
</tr>
<tr>
<td><code>copy_bn</code></td>
<td style="text-align:left">将一个256位大数<code>src</code>按大端法（从高位到低位）拷贝到目标地址<code>dist</code>，使用<code>uint32_t</code>指针以提升拷贝速度。</td>
</tr>
<tr>
<td><code>copy_reverse</code></td>
<td style="text-align:left">将源字节数组<code>src</code>的内容按字节逆序拷贝到目标字节数组<code>dist</code>，拷贝的字节数由<code>n_bytes</code>指定。</td>
</tr>
<tr>
<td><code>sm2_compute_z</code></td>
<td style="text-align:left">计算SM2签名流程中的用户哈希值<code>Z_A</code>，根据标准GB/T32918.2-2016，将用户标识<code>ID_A</code>、公钥<code>pub</code>和其他曲线参数拼接后通过SM3哈希函数生成<code>Z_A</code>。</td>
</tr>
<tr>
<td><code>sm2_signature_generate</code></td>
<td style="text-align:left">生成SM2签名<code>(R,S)</code>，基于用户的密钥对<code>key</code>、用户哈希值<code>Z_A</code>和待签名消息<code>message</code>。该函数遵循GB/T32918.2-2016标准，通过随机数<code>k</code>、椭圆曲线点计算和模运算生成签名。</td>
</tr>
<tr>
<td><code>sm2_signature_verify</code></td>
<td style="text-align:left">验证SM2签名<code>(R,S)</code>的有效性，基于公钥<code>public_key</code>、用户哈希值<code>Z_A</code>和待验证消息<code>message</code>。该函数遵循GB/T32918.2-2016标准，通过一系列椭圆曲线运算和模运算判断签名是否有效，返回验证结果。</td>
</tr>
<tr>
<td><code>sm2_z256_get_booth</code></td>
<td style="text-align:left">获取256位标量<code>k</code>在指定窗口大小下的Booth编码，用于优化窗口化标量乘法算法。根据窗口大小和当前位位置提取相应的位并进行编码转换。</td>
</tr>
<tr>
<td><code>sm2_z256_point_copy_affine</code></td>
<td style="text-align:left">将仿射坐标点<code>SM2_Point</code>复制到Jacobian坐标点<code>SM2_Jacobian_Point</code>，并将<code>Z</code>坐标设置为1，以表示标准化的Jacobian坐标。</td>
</tr>
<tr>
<td><code>sm2_point_add_affine</code></td>
<td style="text-align:left">在Jacobian坐标系中，将Jacobian点<code>P</code>与仿射点<code>Q</code>相加，结果存储在<code>R</code>中。此函数通过将仿射点转换为Jacobian坐标后执行点加法运算，实现不同坐标系点的加法操作。</td>
</tr>
<tr>
<td><code>sm2_point_sub_affine</code></td>
<td style="text-align:left">在Jacobian坐标系中，将Jacobian点<code>P</code>减去仿射点<code>Q</code>，结果存储在<code>R</code>中。此函数通过将仿射点取负后执行点加法运算，实现不同坐标系点的减法操作。</td>
</tr>
<tr>
<td><code>sm2_point_mul_generator</code></td>
<td style="text-align:left">计算基点<code>G</code>的标量乘法<code>R=k*G</code>，使用预计算的点表和Booth算法优化计算过程。该函数通过遍历标量<code>k</code>的Booth编码，结合预计算的点表，高效地计算标量乘法结果。</td>
</tr>
<tr>
<td><code>print_bytes</code></td>
<td style="text-align:left">打印指定字节数组<code>s</code>的前<code>n</code>个字节，以十六进制形式输出。该函数常用于调试和验证数据的正确性。</td>
</tr>
</tbody>
</table>
<h3 id="34-sm2加密和解密功能实现-sm2_encc">3.4 SM2加密和解密功能实现 <code>sm2_enc.c</code></h3>
<p>包含SM2加密解密操作和密钥派生函数</p>
<table>
<thead>
<tr>
<th>函数名称</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>KDF</code></td>
<td>定义SM2标准中所规定的密钥派生函数，生成对应<code>klen</code>长度的比特流</td>
</tr>
<tr>
<td><code>sm2_encrypt</code></td>
<td>用于加密字节串，生成指向生成加密字节串的指针</td>
</tr>
<tr>
<td><code>sm2_decrypt</code></td>
<td>用于解密字节串，将输入的字节串存放到形参中的<code>decrypted</code>指针指向的地址中，同时返回解密成功与否状态</td>
</tr>
</tbody>
</table>
<h3 id="35-safegcd实现-sm2_safegcdc">3.5 safegcd实现 <code>sm2_safegcd.c</code></h3>
<p>SM2算法中存在大量模逆运算，例如在将Jacobian坐标系转换为仿射坐标系时、生成签名时和验证签名计算时等等。同时，模逆运算代价较高，因此需要特别优化。<br>
本小组实现了基于费马小定理和扩展欧几里得算法的模逆算法，综合执行速度和占用空间选择后者作为最终实现。然而，欧几里得算法由于时间非恒定，不能很好抵御侧信道攻击。因此本小组选择Safegcd作为快速模逆实现。</p>
<p><strong>Safegcd实现的函数清单如下：</strong></p>
<table>
<thead>
<tr>
<th>函数名称</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sm2_modinv64_abs</code></td>
<td>计算一个<code>int64_t</code>类型整数的绝对值，避免使用标准库函数以确保与整数大小无关。</td>
</tr>
<tr>
<td><code>sm2_i128_from_i64</code></td>
<td>将一个<code>int64_t</code>类型的整数转换为<code>sm2_int128</code>结构，分离高位和低位。</td>
</tr>
<tr>
<td><code>sm2_i128_eq_var</code></td>
<td>比较两个<code>sm2_int128</code>结构是否相等。</td>
</tr>
<tr>
<td><code>sm2_i128_check_pow2</code></td>
<td>检查一个<code>sm2_int128</code>结构是否等于某个二次幂（可选地取绝对值）。</td>
</tr>
<tr>
<td><code>sm2_modinv64_mul_62</code></td>
<td>计算<code>sm2_modinv64_signed62</code>结构与一个小因子的乘积，结果的除最高位外每一部分都在<code>[0,2^62)</code>范围内。</td>
</tr>
<tr>
<td><code>sm2_modinv64_mul_cmp_62</code></td>
<td>比较两个<code>sm2_modinv64_signed62</code>结构的乘积，返回-1、0或1表示第一个乘积小于、等于或大于第二个乘积。</td>
</tr>
<tr>
<td><code>sm2_i128_to_u64</code></td>
<td>将<code>sm2_int128</code>结构转换为<code>uint64_t</code>，仅返回低64位。</td>
</tr>
<tr>
<td><code>sm2_i128_to_i64</code></td>
<td>将<code>sm2_int128</code>结构转换为<code>int64_t</code>，确保高位是低位的符号扩展。</td>
</tr>
<tr>
<td><code>sm2_mul128</code></td>
<td>计算两个<code>int64_t</code>类型整数的乘积，结果拆分为低64位和高64位。</td>
</tr>
<tr>
<td><code>sm2_i128_mul</code></td>
<td>计算两个<code>int64_t</code>类型整数的乘积，并将结果存储在<code>sm2_int128</code>结构中。</td>
</tr>
<tr>
<td><code>sm2_i128_dissip_mul</code></td>
<td>计算两个<code>int64_t</code>类型整数的乘积，并从<code>sm2_int128</code>结构中扣除高位部分，确保没有溢出或下溢。</td>
</tr>
<tr>
<td><code>sm2_i128_det</code></td>
<td>计算2x2矩阵的行列式，其中矩阵由四个<code>int64_t</code>元素组成，并将结果存储在<code>sm2_int128</code>结构中。</td>
</tr>
<tr>
<td><code>sm2_modinv64_det_check_pow2</code></td>
<td>检查一个转换矩阵的行列式是否等于某个二次幂，支持绝对值检查。</td>
</tr>
<tr>
<td><code>unsigned_mult64</code></td>
<td>计算两个无符号<code>uint64_t</code>整数的乘积，结果拆分为低64位和高64位。</td>
</tr>
<tr>
<td><code>twos_complement</code></td>
<td>对128位无符号数进行二的补码转换，将结果存储在低64位和高64位中。</td>
</tr>
<tr>
<td><code>multiply128</code></td>
<td>将两个有符号<code>LONG64</code>整数相乘，得到128位结果，拆分为低64位和高64位。</td>
</tr>
<tr>
<td><code>sm2_i128_accum_mul</code></td>
<td>将两个<code>int64_t</code>类型整数相乘，并将结果累加到<code>sm2_int128</code>结构中，确保没有溢出或下溢。</td>
</tr>
<tr>
<td><code>sm2_i128_rshift</code></td>
<td>对<code>sm2_int128</code>结构执行有符号的右移操作。</td>
</tr>
<tr>
<td><code>sm2_modinv64_normalize_62</code></td>
<td>规范化一个<code>sm2_modinv64_signed62</code>结构，使其所有部分都在<code>[0,2^62)</code>范围内，并根据需要进行取反。</td>
</tr>
<tr>
<td><code>sm2_modinv64_divsteps_59</code></td>
<td>执行59次除法步骤以计算过渡矩阵和新的<code>zeta</code>值，用于模逆元计算的迭代过程。</td>
</tr>
<tr>
<td><code>sm2_modinv64_update_de_62</code></td>
<td>使用过渡矩阵更新<code>d</code>和<code>e</code>结构，以在模逆元计算过程中保持正确的范围。</td>
</tr>
<tr>
<td><code>sm2_modinv64_update_fg_62</code></td>
<td>使用过渡矩阵更新<code>f</code>和<code>g</code>结构，以在模逆元计算过程中保持正确的范围。</td>
</tr>
<tr>
<td><code>sm2_modinv64</code></td>
<td>计算<code>x</code>关于给定模数的模逆元，并将结果存储回<code>x</code>。</td>
</tr>
<tr>
<td><code>convert_to_signed62</code></td>
<td>将一个256位无符号整数转换为<code>sm2_modinv64_signed62</code>结构，分配到不同的limbs中。</td>
</tr>
<tr>
<td><code>convert_to_sm2_uint256</code></td>
<td>将<code>sm2_modinv64_signed62</code>结构转换回256位无符号整数。</td>
</tr>
<tr>
<td><code>sm2_safegcd_mod_p_inv</code></td>
<td>计算一个256位无符号整数<code>a</code>关于SM2模数<code>P</code>的模逆元，并将结果存储在<code>r</code>中。</td>
</tr>
<tr>
<td><code>sm2_safegcd_mod_n_inv</code></td>
<td>计算一个256位无符号整数<code>a</code>关于SM2模数<code>N</code>的模逆元，并将结果存储在<code>r</code>中。</td>
</tr>
<tr>
<td><code>print_v</code></td>
<td>打印一个<code>sm2_modinv64_signed62</code>结构中的所有limbs。</td>
</tr>
<tr>
<td><code>print128</code></td>
<td>打印两个<code>LONG64</code>整数（低位和高位）作为128位十六进制数。</td>
</tr>
</tbody>
</table>
<p><strong>3.5.1 关键函数详细说明</strong></p>
<ol>
<li>
<p><strong>顶层函数</strong></p>
<ul>
<li><code>sm2_safegcd_mod_p_inv</code> 和 <code>sm2_safegcd_mod_n_inv</code> 是对外接口函数，用于计算给定数 <code>a</code> 关于模数 <code>P</code> 或 <code>N</code> 的模逆元。这两个函数依赖于：
<ul>
<li><code>convert_to_signed62</code>：将输入转换为内部表示。</li>
<li><code>sm2_modinv64</code>：执行模逆元计算。</li>
<li><code>convert_to_sm2_uint256</code>：将内部表示转换回标准的 256 位无符号整数。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>模逆元计算</strong></p>
<ul>
<li><code>sm2_modinv64</code> 是核心函数，执行模逆元的计算过程。它依赖于：
<ul>
<li><code>sm2_modinv64_divsteps_59</code>：执行分步骤计算过渡矩阵和 <code>zeta</code>。</li>
<li><code>sm2_modinv64_update_de_62</code> 和 <code>sm2_modinv64_update_fg_62</code>：更新中间变量 <code>d</code>, <code>e</code>, <code>f</code>, <code>g</code>。</li>
<li>其他辅助函数用于数学运算和检查。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>数学运算辅助函数</strong></p>
<ul>
<li>多个函数用于处理 128 位整数的运算，如：
<ul>
<li><code>sm2_i128_mul</code>、<code>sm2_i128_accum_mul</code>：执行乘法和累加。</li>
<li><code>sm2_i128_det</code>：计算行列式。</li>
<li><code>sm2_i128_rshift</code>：执行右移操作。</li>
<li><code>sm2_i128_to_u64</code>、<code>sm2_i128_to_i64</code>：将 128 位结构转换为 64 位整数。</li>
<li><code>sm2_i128_check_pow2</code>：检查是否为二次幂。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>基本运算函数</strong></p>
<ul>
<li><code>unsigned_mult64</code> 和 <code>multiply128</code> 负责基础的 64 位和 128 位乘法运算。</li>
<li><code>twos_complement</code> 用于处理二的补码转换。</li>
<li><code>sm2_modinv64_mul_62</code> 和 <code>sm2_modinv64_mul_cmp_62</code> 处理特定的乘法和比较操作。</li>
</ul>
</li>
<li>
<p><strong>转换函数</strong></p>
<ul>
<li><code>convert_to_signed62</code> 和 <code>convert_to_sm2_uint256</code> 负责在不同数据表示之间转换。</li>
</ul>
</li>
</ol>
<p><strong>3.5.2 各模块依赖关系</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\safegcd.svg" alt="safegcd"></p>
<h3 id="36-5-naf实现用于加速椭圆曲线标量乘法运算sm2_5_nafc">3.6 5-NAF实现，用于加速椭圆曲线标量乘法运算<code>sm2_5_naf.c</code></h3>
<table>
<thead>
<tr>
<th>函数名称</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>bn256_not_zero</code></td>
<td>检查一个256位的大数是否不为零。</td>
</tr>
<tr>
<td><code>bn256_is_odd</code></td>
<td>判断一个256位的大数是否为奇数（即最低位是否为1）。</td>
</tr>
<tr>
<td><code>bn256_rshift1</code></td>
<td>对一个256位的大数执行逻辑右移1位操作（<code>out=in&gt;&gt;1</code>）。</td>
</tr>
<tr>
<td><code>bn256_add_small</code></td>
<td>将一个小整数（0≤x&lt;2¹⁶）加到一个256位的大数上，支持加1到15。</td>
</tr>
<tr>
<td><code>bn256_sub_small</code></td>
<td>从一个256位的大数中减去一个小整数（0≤x&lt;2¹⁶），支持减1到15。</td>
</tr>
<tr>
<td><code>sm2_compute_5naf</code></td>
<td>计算标量<code>k</code>的5-NAF（非相邻形式）表示，生成对应的数字序列用于标量乘法。</td>
</tr>
<tr>
<td><code>print_bn256</code></td>
<td>以十六进制格式打印一个256位的大数（小端存储，从最高字到最低字）。</td>
</tr>
<tr>
<td><code>sm2_precompute_5naf_window</code></td>
<td>预计算椭圆曲线点<code>P</code>的±1P,±3P,±5P,...,±15P，存储在预计算表中以加速标量乘法。</td>
</tr>
<tr>
<td><code>sm2_jacobian_point_k_mul_5naf</code></td>
<td>使用5-NAF算法在雅可比坐标系下执行椭圆曲线点的标量乘法<code>k*P</code>，结果存储在<code>result</code>中。</td>
</tr>
</tbody>
</table>
<h4 id="361-模块执行流程">3.6.1 模块执行流程</h4>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\5_naf.svg" alt="5-naf"></p>
<h4 id="362-5-非相邻表示法5-non-adjacent-form-5-naf">3.6.2 5-非相邻表示法（5-Non-Adjacent Form, 5-NAF）</h4>
<p>是一种用于优化椭圆曲线标量乘法的算法。通过减少非零数字的数量并利用更大的数字值，5-NAF能够降低椭圆曲线运算的次数，从而提升计算效率。</p>
<div class="markdown-alert markdown-alert-note"><p class="markdown-alert-title"><svg class="octicon octicon-info mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p><p><strong>标量乘法</strong>是椭圆曲线密码学（Elliptic Curve Cryptography, ECC）中的基础运算，定义为：</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mi>P</mi><mo>=</mo><mi>P</mi><mo>+</mo><mi>P</mi><mo>+</mo><mo>⋯</mo><mo>+</mo><mi>P</mi><mspace width="1em"/><mo stretchy="false">(</mo><mi>k</mi><mtext> 次</mtext><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">kP = P + P + \dots + P \quad (k \text{ 次})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:1em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord text"><span class="mord"> </span><span class="mord cjk_fallback">次</span></span><span class="mclose">)</span></span></span></span></p>
<p>其中：</p>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 是椭圆曲线上的一个点。</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 是一个标量（通常是一个大整数）。</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mi>P</mi></mrow><annotation encoding="application/x-tex">kP</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 表示将点 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 与自身相加 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 次。</li>
</ul>
<p>标量乘法在ECC中广泛用于生成公钥、签名以及密钥交换等操作，其效率直接影响到整个密码系统的性能。</p>
</div>
<h4 id="363-非相邻表示法naf概述">3.6.3 非相邻表示法（NAF）概述</h4>
<p><strong>非相邻表示法（Non-Adjacent Form, NAF）</strong> 是一种用于表示整数的二进制形式，其特点是：</p>
<ul>
<li>每一位的数字取值为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mo>±</mo><mn>1</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{0, \pm1\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">1</span><span class="mclose">}</span></span></span></span>。</li>
<li>任何两个非零位之间至少隔一个零位。</li>
</ul>
<p>这种表示法的优点在于它能够减少非零位的数量，从而减少需要执行的椭圆曲线点加法操作次数，提升运算效率。</p>
<p>例如，整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>15</mn></mrow><annotation encoding="application/x-tex">15</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">15</span></span></span></span> 的二进制表示为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1111</mn></mrow><annotation encoding="application/x-tex">1111</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1111</span></span></span></span>，而其NAF表示为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>100</mn><mo lspace="0em" rspace="0em">−</mo><mn>1</mn><mo lspace="0em" rspace="0em">−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">100{-}1{-}1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">100</span><span class="mord"><span class="mord">−</span></span><span class="mord">1</span><span class="mord"><span class="mord">−</span></span><span class="mord">1</span></span></span></span>，其中 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">−</span><span class="mord">1</span></span></span></span> 表示负数。</p>
<h4 id="364-5-naf扩展">3.6.4 5-NAF扩展</h4>
<p><strong>5-非相邻表示法（5-Non-Adjacent Form, 5-NAF）</strong> 是对标准NAF的扩展，其特点包括：</p>
<ul>
<li>使用更大的数字集，例如 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mo>±</mo><mn>1</mn><mo separator="true">,</mo><mo>±</mo><mn>2</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{0, \pm1, \pm2\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">2</span><span class="mclose">}</span></span></span></span>。</li>
<li>仍然保持非相邻的非零位，即任何两个非零位之间至少隔一个零位。</li>
</ul>
<p>通过允许更大的数字值，5-NAF能够进一步减少非零位的数量，从而在保持安全性的前提下，进一步优化运算效率。</p>
<h4 id="365-标准naf的数学定义">3.6.5 标准NAF的数学定义</h4>
<p>一个整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 的NAF表示为：</p>
<p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>k</mi><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><mi>n</mi></munderover><msub><mi>d</mi><mi>i</mi></msub><msup><mn>2</mn><mi>i</mi></msup></mrow><annotation encoding="application/x-tex">k = \sum_{i=0}^{n} d_i 2^i
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:2.9291em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6514em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8747em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span></span></span></span></span></span></span></span></p>
<p>其中：</p>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>∈</mo><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mo>±</mo><mn>1</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">d_i \in \{0, \pm1\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">1</span><span class="mclose">}</span></span></span></span>。</li>
<li>不存在相邻的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">d_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">d_{i+1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9028em;vertical-align:-0.2083em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2083em;"><span></span></span></span></span></span></span></span></span></span> 同时为非零。</li>
</ul>
<h4 id="366-5-naf的数学定义">3.6.6 5-NAF的数学定义</h4>
<p>对于5-NAF，整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> 的表示为：</p>
<p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>k</mi><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><mi>n</mi></munderover><msub><mi>d</mi><mi>i</mi></msub><msup><mn>2</mn><mi>i</mi></msup></mrow><annotation encoding="application/x-tex">k = \sum_{i=0}^{n} d_i 2^i
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:2.9291em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6514em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8747em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span></span></span></span></span></span></span></span></p>
<p>其中：</p>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>∈</mo><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mo>±</mo><mn>1</mn><mo separator="true">,</mo><mo>±</mo><mn>2</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">d_i \in \{0, \pm1, \pm2\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">2</span><span class="mclose">}</span></span></span></span>。</li>
<li>不存在相邻的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">d_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">d_{i+1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9028em;vertical-align:-0.2083em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2083em;"><span></span></span></span></span></span></span></span></span></span> 同时为非零。</li>
</ul>
<p>这种表示法允许每一位的数字值更大，从而在保持非相邻的特性下，进一步减少非零位的数量。</p>
<h4 id="367-5-naf转换算法">3.6.7 5-NAF转换算法</h4>
<p>将一个整数转换为5-NAF的过程类似于标准NAF，但需要适应更大的数字集。以下是一个基本的5-NAF转换算法：</p>
<p><strong>算法步骤</strong></p>
<ol>
<li>
<p><strong>初始化</strong>：</p>
<ul>
<li>设<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>为要转换的整数。</li>
<li>初始化<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">i = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>。</li>
<li>初始化表示<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span>为所有位为0。</li>
</ul>
</li>
<li>
<p><strong>迭代处理</strong>：</p>
<ul>
<li>当<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>&gt;</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">k &gt; 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>时，执行以下步骤：
<ol>
<li>如果<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>为奇数，则计算<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>=</mo><mi>k</mi><mspace></mspace><mspace width="0.6667em"/><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mtext> </mtext><mtext> </mtext><mn>4</mn></mrow><annotation encoding="application/x-tex">d_i = k \mod 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.6667em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">4</span></span></span></span>。
<ul>
<li>如果<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>&gt;</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_i &gt; 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>，则设置<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>=</mo><msub><mi>d</mi><mi>i</mi></msub><mo>−</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">d_i = d_i - 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">4</span></span></span></span>。</li>
</ul>
</li>
<li>否则，设置<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mi>i</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_i = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>。</li>
<li>更新<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mfrac><mrow><mi>k</mi><mo>−</mo><msub><mi>d</mi><mi>i</mi></msub></mrow><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">k = \frac{k - d_i}{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.2412em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8962em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3281em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>。</li>
<li>增加位索引<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>=</mo><mi>i</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">i = i + 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7429em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>。</li>
</ol>
</li>
</ul>
</li>
<li>
<p><strong>终止</strong>：</p>
<ul>
<li>当 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">k = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>  时，算法结束，输出 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> 作为5-NAF表示。</li>
</ul>
</li>
</ol>
<h4 id="368-5-naf优化">3.6.8 5-NAF优化</h4>
<ol>
<li>
<p><strong>减少非零位数量</strong>：</p>
<ul>
<li>通过允许更大的数字值，5-NAF可以在相同的位数内表示更大的整数，进一步减少非零位的数量。</li>
</ul>
</li>
<li>
<p><strong>降低椭圆曲线运算次数</strong>：</p>
<ul>
<li>每个非零位通常对应一次点加法或点倍加运算，减少非零位数量直接降低了总体运算次数。</li>
</ul>
</li>
<li>
<p><strong>提高计算效率</strong>：</p>
<ul>
<li>更少的运算次数意味着更快的标量乘法计算，提升整个密码系统的性能。</li>
</ul>
</li>
<li>
<p><strong>保持安全性</strong>：</p>
<ul>
<li>虽然使用更大的数字集，但5-NAF仍保持了非相邻的特性，确保不易受到侧信道攻击。</li>
</ul>
</li>
</ol>
<h4 id="369-5-naf示例">3.6.9 5-NAF示例</h4>
<table>
<thead>
<tr>
<th>位(i)</th>
<th>(k)</th>
<th>奇偶性</th>
<th>(d_i=k\mod4)</th>
<th>调整后的(d_i)</th>
<th style="text-align:center">更新后的(k)</th>
<th style="text-align:center">5-NAF表示</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>37</td>
<td>奇数</td>
<td>1</td>
<td>1</td>
<td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>37</mn><mo>−</mo><mn>1</mn></mrow><mn>2</mn></mfrac><mo>=</mo><mn>18</mn></mrow><annotation encoding="application/x-tex">\frac{37-1}{2}=18</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1901em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">37</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">18</span></span></span></span></td>
<td style="text-align:center">1</td>
</tr>
<tr>
<td>1</td>
<td>18</td>
<td>偶数</td>
<td>2</td>
<td>2</td>
<td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>18</mn><mo>−</mo><mn>2</mn></mrow><mn>2</mn></mfrac><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">\frac{18-2}{2}=8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1901em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">18</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">8</span></span></span></span></td>
<td style="text-align:center">1,2</td>
</tr>
<tr>
<td>2</td>
<td>8</td>
<td>偶数</td>
<td>0</td>
<td>0</td>
<td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>8</mn><mo>−</mo><mn>0</mn></mrow><mn>2</mn></mfrac><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">\frac{8-0}{2}=4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1901em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">8</span><span class="mbin mtight">−</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">4</span></span></span></span></td>
<td style="text-align:center">1,2,0</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>偶数</td>
<td>0</td>
<td>0</td>
<td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>4</mn><mo>−</mo><mn>0</mn></mrow><mn>2</mn></mfrac><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">\frac{4-0}{2}=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1901em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">4</span><span class="mbin mtight">−</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span></td>
<td style="text-align:center">1,2,0,0</td>
</tr>
<tr>
<td>4</td>
<td>2</td>
<td>偶数</td>
<td>2</td>
<td>2</td>
<td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>2</mn><mo>−</mo><mn>2</mn></mrow><mn>2</mn></mfrac><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\frac{2-2}{2}=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1901em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span></td>
<td style="text-align:center">1,2,0,0,2</td>
</tr>
</tbody>
</table>
<p>因此，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>37</mn></mrow><annotation encoding="application/x-tex">37</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">37</span></span></span></span> 的5-NAF表示为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>0</mn><mo separator="true">,</mo><mn>0</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[1, 2, 0, 0, 2]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">2</span><span class="mclose">]</span></span></span></span>，即：</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>37</mn><mo>=</mo><mn>1</mn><mo>⋅</mo><msup><mn>2</mn><mn>0</mn></msup><mo>+</mo><mn>2</mn><mo>⋅</mo><msup><mn>2</mn><mn>1</mn></msup><mo>+</mo><mn>0</mn><mo>⋅</mo><msup><mn>2</mn><mn>2</mn></msup><mo>+</mo><mn>0</mn><mo>⋅</mo><msup><mn>2</mn><mn>3</mn></msup><mo>+</mo><mn>2</mn><mo>⋅</mo><msup><mn>2</mn><mn>4</mn></msup></mrow><annotation encoding="application/x-tex">37 = 1 \cdot 2^0 + 2 \cdot 2^1 + 0 \cdot 2^2 + 0 \cdot 2^3 + 2 \cdot 2^4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">37</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span></p>
<h3 id="37-jsf-多标量乘法优化-sm2_5_jsfc">3.7 JSF 多标量乘法优化 <code>sm2_5_jsf.c</code></h3>
<p>在椭圆曲线密码学（ECC）领域，单标量乘法的优化始终是众多学者重点研究的方向。</p>
<p>学者们普遍认为，计算标量乘法的关键在于降低标量中的数据密集度，以此从根源上减少乘法运算的次数。经降低数据密度后所得到的数据形式，被称作稀疏形式。</p>
<p>当下，二进制双加法 [2] 、非邻接形式（NAF，Non-ajacent Form）[3,4] 以及窗口非相邻形式 [5] 是主流的稀疏形式算法。这些算法的核心思路是降低标量的平均汉明权重，进而减少额外的计算量。然而实际上，部分算法尽管在单标量乘法的优化上效果良好，但在多标量乘法运算中，却会引入更多的额外计算开销 [6,7] 。尤其在使用 ECDSA 时，更多涉及的是多倍点乘法运算。</p>
<p>所以在实际应用中，迫切需要对多倍点乘法进行更为深入的优化。为达成这一目标，联合稀疏形式（JSF，Joint Sparse Form）应运而生，这是一种采用字符集大小为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3</span></span></span></span> 的多标量稀疏形式生成方式，通常我们将此版本的JSF 称为 JSF-3。JSF-3 生成算法虽能够一次性生成一对标量的稀疏形式，但其代价是较高的计算复杂度。并且，JSF-3 生成的标量的平均联合汉明密度与 NAF相比，优势并不明显。</p>
<p>李学磊等 [8] 在 JSF-3 的基础上，将字符集扩展为五元，命名为 JSF-5。这一改进使得平均联合汉明密度从 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0.5</mn><mi>l</mi></mrow><annotation encoding="application/x-tex">0.5l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">0.5</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span> 降至 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0.38</mn><mi>l</mi></mrow><annotation encoding="application/x-tex">0.38l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">0.38</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>，这里的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span> 代表数据长度。王念平 [9] 在此基础上又提出了一种新的 JSF-5 算法，能进一步将平均联合汉明密度降低至 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>3</mn></mrow><annotation encoding="application/x-tex">1/3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/3</span></span></span></span>。尽管学者们持续对 JSF 进行改进，使得平均汉明密度不断降低，但生成 JSF 的计算复杂度依旧居高不下，并且和 NAF 一样，需要使用两个额外的数据空间来分别存储两个标量的稀疏形式。</p>
<p>齐鲁工业大学陈鑫泽[1]等人深入研究这些问题后，提出在预计算阶段运用safegcd 算法开展坐标变换工作，同时引入 Co-Z 公式来优化点加运算。在生成多标量稀疏形式时，对 JSF-5 稀疏形式的结果重新编码，并将预计算结果存储到数组中，以此让后续计算更为便捷。虽然这种改进后的编码方法会额外占用少量存储空间，但却能消除大部分判断开销。针对大整数重复计算的问题，陈鑫泽等人[1]进一步优化该方法，引入全新的 JSF-5 数据分段算法</p>
<p><small><strong>陈鑫泽等人提出的多标量乘法流程图</strong></small></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_1.png" alt="jsf-5"></p>
<p><small><strong>陈鑫泽等人提出的JSF-5预计算点的索引编码</strong></small></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_2.png" alt="jsf-5"></p>
<h4 id="371-算法原理">3.7.1 算法原理*</h4>
<p>观察输入数据与预计算数据的特点，在预计算过程中，假设 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 为椭圆曲线的基点，根据 SM2 和 ECC 的给定参数，预计算过程中的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><mi>P</mi></mrow><annotation encoding="application/x-tex">3P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord">3</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 可以通过提前计算（程序执行之前）获得并存储，进一步提高效率，而自由选取的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span></span></span></span> 点则要在预计算过程中计算。由于椭圆曲线坐标系的特性，仿射坐标系中的曲线上的两个点 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">-P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 有着同样的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span> 坐标，并有着相反的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span> 坐标，即<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>X</mi><mtext>，</mtext><mi>Y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(X，Y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord cjk_fallback">，</span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>X</mi><mtext>，</mtext><mo>−</mo><mi>Y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(X，-Y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord cjk_fallback">，</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span></span></span></span>。而且在仿射坐标系中，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">-P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 没有 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标，而在投影坐标系中，当 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标为 1 时，两个点就相 当于仿射坐标系中的点，再根据坐标系换算公式，可以默认仿射坐标系下的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">-P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 在雅可比坐标系中有着相同的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标且为 1，换句话说，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 点和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><mi>P</mi></mrow><annotation encoding="application/x-tex">3P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord">3</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 点的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标 均为 1。 同时，两个不同的点 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>+</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">Q+P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 与 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>−</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">Q-P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 具有相同的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标，其他的诸如 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>+</mo><mn>3</mn><mi>P</mi></mrow><annotation encoding="application/x-tex">Q+3P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord">3</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 与 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>−</mo><mn>3</mn><mi>P</mi></mrow><annotation encoding="application/x-tex">Q-3P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord">3</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> 也具有相同的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi></mrow><annotation encoding="application/x-tex">Z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span></span></span></span> 坐标。假设参与运算的点为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>=</mo><mo stretchy="false">(</mo><mi>X</mi><mi>A</mi><mo separator="true">,</mo><mi>Y</mi><mi>A</mi><mo separator="true">,</mo><mi>Z</mi><mi>A</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">A=(XA,YA,ZA)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord mathnormal">A</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord mathnormal">A</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mord mathnormal">A</span><span class="mclose">)</span></span></span></span>和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mo>=</mo><mo stretchy="false">(</mo><mi>X</mi><mi>A</mi><mo separator="true">,</mo><mi>Y</mi><mi>A</mi><mo separator="true">,</mo><mi>Z</mi><mi>B</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">B=(XA,YA,ZB)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord mathnormal">A</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord mathnormal">A</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">ZB</span><span class="mclose">)</span></span></span></span>， 它们的取值为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">Q</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><mi>P</mi></mrow><annotation encoding="application/x-tex">3P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord">3</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><mi>Q</mi></mrow><annotation encoding="application/x-tex">3Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord">3</span><span class="mord mathnormal">Q</span></span></span></span>，根据不同的运算组合，所涉及的点的Z坐标有如下特点：</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_3.png" alt="jsf-5"></p>
<p>根据这个特点，分别提出了XYZ和XYZ1的两种Co-Z算法，用于快速计算两点P1和P2的点加运算和点减运算：P1+P2和P1-P2.</p>
<p><strong>(1) XYZ: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mi>A</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">ZA=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mi>B</mi><mo mathvariant="normal">≠</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">ZB \neq 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">ZB</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span></strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_4.png" alt="jsf-5"></p>
<p><strong>(2) XYZ: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mi>A</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">ZA=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mi>B</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">ZB=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">ZB</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span></strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_5.png" alt="jsf-5"></p>
<p><strong>(3) 预计算点使用safegcd进行坐标还原</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_6.png" alt="jsf-5"></p>
<h4 id="372-新的jsf-5联合稀疏形式">3.7.2 新的JSF-5联合稀疏形式</h4>
<p>陈鑫泽等人[1]开发了一种新的 JSF-5 单数组技术，通过编码稀疏形式的结果，不仅实现了两个数组的合并， 还保证了合并后的数据与预计算表相匹配。这样做不但消除了判断逻辑，还降低了执行过程的整体开销。JSF-5 单数组方法的核心在于利用每次迭代中标量奇偶 性的变化来调整 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">x_{j}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7167em;vertical-align:-0.2861em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span>和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>y</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">y_{j}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7167em;vertical-align:-0.2861em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span> 的值，并依据这些值来确定当前位的输出，极大地减少了判断操作的需求。 该方法通过直接索引预先计算的值来消除冗余的判断操作。具体来说，通过对算法的深入分析，发现可以使用取低三位运算来代替算法中的模 8 运算，取值 的结果作为索引来访问一个预建立的统计表。这种方法的核心在于，算法每轮操作的输出值主要由输入标量的最后三位决定。因此，他们首先详细分析了在不同操作逻辑下输出值的变化规律，并据此构建了 3 个统计表，该表仅依赖于输入标 量最后三位的值。这种改进显著提升了算法的执行效率，因为它减少了计算过程 中不必要的运算，并使得索引值的获取更加直接和快速。</p>
<p><small><strong>输入x和y的联合稀疏形式以及预计算点索引的统一编码表</strong></small></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_7.png" alt="jsf-5"></p>
<p><strong>(1) 索引计算方法</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_8.png" alt="jsf-5"></p>
<p><strong>(2) 由统一编码表求得双标量<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span>的单数组联合稀疏形式分段优化算法</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_9.png" alt="jsf-5"></p>
<h4 id="373-多标量优化的jsf-5算法求xg--yq">3.7.3 多标量优化的JSF-5算法求<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>x</mi><mo stretchy="false">]</mo><mi>G</mi></mrow><annotation encoding="application/x-tex">[x]G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">x</span><span class="mclose">]</span><span class="mord mathnormal">G</span></span></span></span> + <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>y</mi><mo stretchy="false">]</mo><mi>Q</mi></mrow><annotation encoding="application/x-tex">[y]Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">]</span><span class="mord mathnormal">Q</span></span></span></span></h4>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\jsf-5_10.png" alt="jsf-5"></p>
<h4 id="374-实验">3.7.4 实验</h4>
<p><strong>在验签算法中计算<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>s</mi><mo stretchy="false">]</mo><mi>G</mi><mo>+</mo><mo stretchy="false">[</mo><mi>t</mi><mo stretchy="false">]</mo><msub><mi>P</mi><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">[s]G + [t]P_a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">s</span><span class="mclose">]</span><span class="mord mathnormal">G</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">t</span><span class="mclose">]</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></strong></p>
<ol>
<li>使用计算基点的k倍点最快的方法（窗口大小为7的预计算方法）计算[s]G，并且使用通用的比滑动窗口法略快的k倍点算法5-NAF计算[t]Pa。</li>
</ol>
<p><strong>验签时间: 2.031ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\exe_1.png" alt="jsf-5"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\exe_2.png" alt="jsf-5"></p>
<ol start="2">
<li>使用优化的JSF-5算法计算多标量乘法<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>s</mi><mo stretchy="false">]</mo><mi>G</mi><mo>+</mo><mo stretchy="false">[</mo><mi>t</mi><mo stretchy="false">]</mo><msub><mi>P</mi><mi>a</mi></msub></mrow><annotation encoding="application/x-tex">[s]G + [t]P_a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">s</span><span class="mclose">]</span><span class="mord mathnormal">G</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">t</span><span class="mclose">]</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></li>
</ol>
<p><strong>验签时间: 2.034ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\exe_3.png" alt="jsf-5"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\exe_4.png" alt="jsf-5"></p>
<h4 id="375-结论">3.7.5 结论</h4>
<p>从实验可以看出，尽管使用了最快的预计算方法（窗口为7）与5-NAF算法来计算多标量乘法，优化后5-jsf算法仍然可以接近该用时，但是5-jsf算法的预计算点仅13个点，而最快计算[k]G的预计算方法，窗口为7时，预计算点有37*64=2368个。
因此可以看出5-jsf算法的优越性。</p>
<h3 id="38-基于预计算的基点的倍点kg运算优化">3.8 基于预计算的基点的倍点<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>k</mi><mo stretchy="false">]</mo><mi>G</mi></mrow><annotation encoding="application/x-tex">[k]G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">]</span><span class="mord mathnormal">G</span></span></span></span>运算优化</h3>
<h4 id="381-优化动机">3.8.1 优化动机</h4>
<p>在签名、验签、加解密过程中，会用到计算基点的<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>倍点运算，并且该计算消耗的时间占比很大，传统的滑动窗口法、NAF算法适合通用的倍点运算，优化空间比较少，因此采用预计算G点的多窗口倍点，可以极大减少倍点运算的次数。</p>
<h4 id="382-优化思路">3.8.2 优化思路</h4>
<p><strong>1. 选取窗口，计算各个窗口的相应倍点</strong></p>
<p>假设窗口大小window=7，则需要计算256/7&gt;36，向上取整为37个窗口的预计算点，每个窗口需要计算从1到2^7-1共127个倍点，以第二个窗口为例，需要预计算的倍点从：</p>
<p>0b000000000000....(0000001)(0000000)</p>
<p>到 0b000000000000....(1111111)(0000000)共127个倍点。（备注：仅递增该窗口的值，其余窗口为0，因此共127个点）</p>
<p>最后一个窗口大小仅有256-36*7=4，因此预计算倍点从：0b(0001)(0000000)....(0000000)到0b(1111)(0000000)...(0000000)共15个倍点。</p>
<p>则总体预计算倍点数量为：36*127 + 15 = 4587个倍点，共占286KB内存，可见预计算量很大。</p>
<p><strong>2. 将<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>按照窗口分割，遍历每一个窗口的值，如果窗口值大于0，则直接从相应窗口的相应倍点取出，然后与当前点进行点加，最后得到的点即为最终的<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>k</mi><mo stretchy="false">]</mo><mi>G</mi></mrow><annotation encoding="application/x-tex">[k]G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">]</span><span class="mord mathnormal">G</span></span></span></span>点。</strong></p>
<p>假设当前已经经过计算得到当前点R，并且当前窗口为第7个窗口，窗口值为0b1001101，则该窗口对应的倍点的值应为</p>
<p>0b(0000)(0000000)...(0000000)(1001101)(0000000)...(0000000)，</p>
<p>直接从第7个预计算窗口的第0b1001101，即取出第77个点与点R相加，得到新的点R，然后进入下一个窗口。</p>
<p><strong>3. 利用点的对称性进行优化，极大节省空间</strong></p>
<p>使用上述方法预计算量很大，可以用利用倍点的对称性进行优化。
基本思想</p>
<p>假设窗口为7，将窗口内的每一个点都减去窗口的中间点，即将点的范围从1到127（实际不这样，方便理解），变为-63到63，并且由于点的对称性，可以只存储一半，即存储非负数的一半，即1到64个倍点。</p>
<p>当计算到该窗口时，仅需先将当前点R加上该窗口的最后一个倍点，即第64个倍点。然后根据当前窗口的值V，如果值小于64，比如34，则减去第（64-34）= 30个点，得到新的点R；如果大于64，比如80，则加上第（80-64）=16个点，得到新的点R。</p>
<p>公式: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo>=</mo><mi>R</mi><mo>+</mo><mo stretchy="false">[</mo><mn>64</mn><mo>+</mo><mi>a</mi><mo stretchy="false">]</mo><mi>G</mi></mrow><annotation encoding="application/x-tex">R = R + [64 + a]G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">64</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">a</span><span class="mclose">]</span><span class="mord mathnormal">G</span></span></span></span> (如果 V &gt; 64, 则 a = V - 64; 如果 V &lt; 64, 则a = 64 - V)</p>
<p><strong>4. 最终优化：利用booth编码节省计算量和预计算空间</strong></p>
<ol>
<li>上述对称性优化的缺陷</li>
</ol>
<p>使用对称性固然可以减少预计算的空间，但也会增加一次点加运算，因为每个窗口都会与该窗口最后一个预计算倍点进行点加运算，因此耗时增加。</p>
<ol start="2">
<li>使用booth编码进行优化</li>
</ol>
<p>使用booth编码可以同时具备上述两种优化的优势，在不增加多余点加运算量的同时还能根据对称性将预计算点的数量减半。</p>
<p>思路</p>
<p>存储的预计算点与第三节一样，预计算的点从：</p>
<p>0b000000000000...(0000001)...(0000000)<br>
到0b0000000000...(1000000)...(0000000)</p>
<p>共64个点，相比第二节，少了从1000001到1111111的共63个点，存储空间减半。</p>
<p>窗口值的优化:</p>
<p>现在窗口值不再是窗口的字面值，而是将当前窗口的右边一个比特纳入计算。</p>
<p>Booth编码为：</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>当</mtext><mi>i</mi><mo>=</mo><mn>0</mn><mtext>时</mtext><mo separator="true">,</mo><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mi>i</mi></msub><mo>=</mo><mo stretchy="false">(</mo><mi>k</mi><mo>&lt;</mo><mo>&lt;</mo><mn>1</mn><mo stretchy="false">)</mo><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>−</mo><mi>k</mi><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">当 i = 0时, Booth_{i} = (k &lt;&lt; 1) \&amp; Mask - k \&amp; Mask,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord cjk_fallback">当</span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">0</span><span class="mord cjk_fallback">时</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mpunct">,</span></span></span></span><br>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>当</mtext><mi>i</mi><mo mathvariant="normal">≠</mo><mn>0</mn><mtext>时，</mtext><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mi>i</mi></msub><mo>=</mo><mi>k</mi><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>−</mo><mo stretchy="false">(</mo><mi>k</mi><mo>&gt;</mo><mo>&gt;</mo><mn>1</mn><mo stretchy="false">)</mo><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi></mrow><annotation encoding="application/x-tex"> 当 i \neq 0时， Booth_{i} = k \&amp; Mask - (k &gt;&gt; 1) \&amp; Mask</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord cjk_fallback">当</span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord">0</span><span class="mord cjk_fallback">时，</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span></p>
<p>证明：
设 k 由如下表示，当不是第一个窗口时，<br>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mi>o</mi><mi>o</mi><mi>t</mi><mi>h</mi><mo>=</mo><mi>V</mi><mi mathvariant="normal">&amp;</mi><mi>m</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>−</mo><mo stretchy="false">(</mo><mi>V</mi><mo>&gt;</mo><mo>&gt;</mo><mn>1</mn><mo stretchy="false">)</mo><mi mathvariant="normal">&amp;</mi><mi>m</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mi>x</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><mo>−</mo><mo stretchy="false">(</mo><mi>W</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">booth = V \&amp; mask - (V &gt;&gt; 1) \&amp; mask = (2x + b)-(W)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">V</span><span class="mord">&amp;</span><span class="mord mathnormal">ma</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.22222em;">V</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord">&amp;</span><span class="mord mathnormal">ma</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mclose">)</span></span></span></span><br>
其中，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>=</mo><msup><mn>2</mn><mrow><mi>w</mi><mi>i</mi><mi>n</mi><mi>d</mi><mi>o</mi><mi>w</mi></mrow></msup><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">mask = 2^{window} - 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">ma</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.9324em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mord mathnormal mtight">in</span><span class="mord mathnormal mtight">d</span><span class="mord mathnormal mtight">o</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>， <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>w</mi></mrow><annotation encoding="application/x-tex">w</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span></span></span></span> 为该窗口的字面值</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-1.png" alt="window1"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-2.png" alt="window2"></p>
<p>第二节的窗口表示为：</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><msup><mi>W</mi><mn>37</mn></msup><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>36</mn></mrow></msup><mo>+</mo><msup><mi>W</mi><mn>36</mn></msup><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>35</mn></mrow></msup><mo>+</mo><msup><mi>W</mi><mn>35</mn></msup><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>34</mn></mrow></msup></mrow><annotation encoding="application/x-tex"> = W^{37}*2^{7*36}+W^{36}*2^{7*35}+W^{35}*2^{7*34} </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">37</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">36</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">35</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span></span></span></span></span></span></span></span></span></span></span></span><br>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>36</mn></msub><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>36</mn></mrow></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>35</mn></msub><mo>+</mo><mi>b</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>35</mn></mrow></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>34</mn></msub><mo>+</mo><mi>c</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>34</mn></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex"> = (X_{36}*2^{7*36}+(X_{35}+b*2^{6})*2^{7*35}+(X_{34}+c*2^{6})*2^{7*34}) </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">36</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">35</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4653em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></p>
<p>本节的三个窗口的Booth编码:</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>36</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mo>∗</mo><msub><mi>X</mi><mn>36</mn></msub><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><mo>−</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>36</mn></msub><mo stretchy="false">)</mo><mo>=</mo><msub><mi>X</mi><mn>36</mn></msub><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex"> Booth_{36} = (2 * X_{36} + b) - (X_{36}) = X_{36} + b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>35</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mo>∗</mo><msub><mi>X</mi><mn>35</mn></msub><mo>+</mo><mi>c</mi><mo stretchy="false">)</mo><mo>−</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>35</mn></msub><mo>+</mo><mi>b</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>=</mo><msub><mi>X</mi><mn>35</mn></msub><mo>−</mo><mi>b</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo>+</mo><mi>c</mi></mrow><annotation encoding="application/x-tex"> Booth_{35} = (2 * X_{35} + c) - (X_{35} + b * 2^{6}) = X_{35} - b * 2^{6} + c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">c</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>34</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mo>∗</mo><msub><mi>X</mi><mn>34</mn></msub><mo>+</mo><mi>d</mi><mo stretchy="false">)</mo><mo>−</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>34</mn></msub><mo>+</mo><mi>c</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>=</mo><msub><mi>X</mi><mn>34</mn></msub><mo>−</mo><mi>c</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo>+</mo><mi>d</mi></mrow><annotation encoding="application/x-tex"> Booth_{34} = (2 * X_{34} + d) - (X_{34} + c * 2^{6}) = X_{34} - c * 2^{6} + d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">d</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4653em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4653em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span></p>
<p>该数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>三个窗口的booth表示:</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>36</mn></msub><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>36</mn></mrow></msup><mo>+</mo><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>35</mn></msub><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>35</mn></mrow></msup><mo>+</mo><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>34</mn></msub><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>34</mn></mrow></msup></mrow><annotation encoding="application/x-tex"> = Booth_{36} * 2^{7*36} + Booth_{35}*2^{7*35} + Booth_{34} * 2 ^{7*34}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">36</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">35</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span></span></span></span></span></span></span></span></span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>36</mn></msub><mo stretchy="false">)</mo><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>36</mn></mrow></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>35</mn></msub><mo>+</mo><mi>b</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>35</mn></mrow></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>X</mi><mn>34</mn></msub><mo>+</mo><mi>c</mi><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo stretchy="false">)</mo><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>34</mn></mrow></msup><mo>+</mo><mi>d</mi><mo>∗</mo><msup><mn>2</mn><mrow><mn>7</mn><mo>∗</mo><mn>34</mn></mrow></msup></mrow><annotation encoding="application/x-tex"> = (X_{36}) * 2^{7*36} + (X_{35}+b*2^{6})*2^{7*35}+(X_{34}+c*2^{6})*2^{7*34}+d*2^{7*34}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">36</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">36</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">35</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">35</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">34</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4653em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span></span></span></span></span></span></span></span></span></span></span></span></p>
<p>由此发现，booth表示与第二节一致，但是多了一个数，也就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi><mo>∗</mo><msup><mn>2</mn><mrow><mo stretchy="false">(</mo><mn>7</mn><mo>∗</mo><mn>34</mn><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">d*2^{(7*34)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">7</span><span class="mbin mtight">∗</span><span class="mord mtight">34</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>。以此类推，到第一个窗口时，会比第二节的表示多一个 ，因此第一个窗口需要将该多余值给抵消掉。</p>
<p>因此需要一个条件判断，当到第一个窗口时，booth编码应变成原窗口值减去该多余值：</p>
<p class="katex-block"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>0</mn></msub><mo>=</mo><msub><mi>W</mi><mn>0</mn></msub><mo>−</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>7</mn></msup><mo>=</mo><msub><mi>X</mi><mn>0</mn></msub><mo>+</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo>−</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>7</mn></msup></mrow><annotation encoding="application/x-tex">Booth_{0} = W_{0} - k_{6} * 2^{7} = X_{0} + k_{6} * 2^{6} - k_{6} * 2^{7} 
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.9474em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p>其中，这样才能与多余的项抵消，而</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>X</mi><mn>0</mn></msub><mo>+</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo>−</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>7</mn></msup></mrow><annotation encoding="application/x-tex">X_{0} + k_{6} * 2^{6} - k_{6} * 2^{7}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span></span></span></span></span></span></span></span></span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><msub><mi>X</mi><mn>0</mn></msub><mo>−</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup></mrow><annotation encoding="application/x-tex">=X_{0} - k_{6} * 2^{6}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mn>2</mn><mo>∗</mo><msub><mi>X</mi><mn>0</mn></msub><mo>−</mo><mo stretchy="false">(</mo><msub><mi>k</mi><mn>6</mn></msub><mo>∗</mo><msup><mn>2</mn><mn>6</mn></msup><mo>+</mo><msub><mi>X</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">=2*X_{0}-(k_{6}*2^{6}+X_{0})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0315em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0785em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mo stretchy="false">(</mo><msub><mi>W</mi><mn>0</mn></msub><mo>&lt;</mo><mo>&lt;</mo><mn>1</mn><mo stretchy="false">)</mo><mo>−</mo><msub><mi>W</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">=(W_{0}&lt;&lt;1)-W_{0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></p>
<p>因此, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mi>o</mi><mi>o</mi><mi>t</mi><msub><mi>h</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><msub><mi>W</mi><mn>0</mn></msub><mo>&lt;</mo><mo>&lt;</mo><mn>1</mn><mo stretchy="false">)</mo><mo>−</mo><msub><mi>W</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mi>k</mi><mo>&lt;</mo><mo>&lt;</mo><mn>1</mn><mo stretchy="false">)</mo><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo>−</mo><mo stretchy="false">(</mo><mi>k</mi><mi mathvariant="normal">&amp;</mi><mi>M</mi><mi>a</mi><mi>s</mi><mi>k</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">Booth_{0} = (W_{0}&lt;&lt;1) - W_{0} = (k &lt;&lt; 1) \&amp; Mask - (k \&amp; Mask)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8444em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">t</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord">&amp;</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">)</span></span></span></span></p>
<p><strong>5. 最终算法表示</strong></p>
<ol>
<li>Booth算法</li>
</ol>
<pre><code class="language-c"><span class="hljs-type">int</span> <span class="hljs-title function_">sm2_get_booth</span><span class="hljs-params">(<span class="hljs-type">const</span> <span class="hljs-type">uint64_t</span>* a, <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> window_size, <span class="hljs-type">int</span> i)</span>
{
    <span class="hljs-type">uint64_t</span> mask = (<span class="hljs-number">1</span> &lt;&lt; window_size) - <span class="hljs-number">1</span>;
    <span class="hljs-type">uint64_t</span> wbits;
    <span class="hljs-type">int</span> n, j;
    <span class="hljs-keyword">if</span> (i == <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">return</span> (<span class="hljs-type">int</span>)((a[<span class="hljs-number">0</span>] &lt;&lt; <span class="hljs-number">1</span>) &amp; mask) - (<span class="hljs-type">int</span>)(a[<span class="hljs-number">0</span>] &amp; mask);
    }
    j = i * window_size - <span class="hljs-number">1</span>;
    n = j / <span class="hljs-number">64</span>; <span class="hljs-comment">// 第几个数</span>
    j = j % <span class="hljs-number">64</span>; <span class="hljs-comment">// 第几个bit</span>
    wbits = a[n] &gt;&gt; j; <span class="hljs-comment">// 当前窗口的值，共7+1=8个比特</span>
    <span class="hljs-keyword">if</span> ((<span class="hljs-number">64</span> - j) &lt; (<span class="hljs-type">int</span>)(window_size + <span class="hljs-number">1</span>) &amp;&amp; n &lt; <span class="hljs-number">3</span>) {
        wbits |= a[n + <span class="hljs-number">1</span>] &lt;&lt; (<span class="hljs-number">64</span> - j);
    }
    <span class="hljs-keyword">return</span> (<span class="hljs-type">int</span>)(wbits &amp; mask) - (<span class="hljs-type">int</span>)((wbits &gt;&gt; <span class="hljs-number">1</span>) &amp; mask);
}
</code></pre>
<ol start="2">
<li>基点多倍点算法<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mi>k</mi><mo stretchy="false">]</mo><mi>G</mi></mrow><annotation encoding="application/x-tex">[k]G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">]</span><span class="mord mathnormal">G</span></span></span></span></li>
</ol>
<pre><code class="language-c"><span class="hljs-type">void</span> <span class="hljs-title function_">sm2_point_mul_generator</span><span class="hljs-params">(SM2_Jacobian_Point *R, <span class="hljs-type">const</span> <span class="hljs-type">uint64_t</span>* k)</span>
{
    <span class="hljs-meta">#<span class="hljs-keyword">ifdef</span> PRE_G_WINDOW_7</span>
    <span class="hljs-type">size_t</span> window_size = <span class="hljs-number">7</span>;
    <span class="hljs-meta">#<span class="hljs-keyword">elif</span> defined PRE_G_WINDOW_5</span>
    <span class="hljs-type">size_t</span> window_size = <span class="hljs-number">5</span>;
    <span class="hljs-meta">#<span class="hljs-keyword">else</span></span>
    <span class="hljs-type">size_t</span> window_size = <span class="hljs-number">3</span>;
    <span class="hljs-meta">#<span class="hljs-keyword">endif</span></span>
    <span class="hljs-type">int</span> R_infinity = <span class="hljs-number">1</span>;
    <span class="hljs-type">int</span> n = (<span class="hljs-number">256</span> + window_size - <span class="hljs-number">1</span>)/window_size;
    <span class="hljs-type">int</span> i;

    <span class="hljs-keyword">for</span> (i = n - <span class="hljs-number">1</span>; i &gt;= <span class="hljs-number">0</span>; i--) {
        <span class="hljs-type">int</span> booth = sm2_get_booth(k, window_size, i);
        <span class="hljs-keyword">if</span> (R_infinity) {
            <span class="hljs-keyword">if</span> (booth != <span class="hljs-number">0</span>) {
                sm2_z256_point_copy_affine(R, &amp;g_pre_comp[i][booth - <span class="hljs-number">1</span>]);
                R_infinity = <span class="hljs-number">0</span>;
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">if</span> (booth &gt; <span class="hljs-number">0</span>) {
                sm2_point_add_affine(R, R, &amp;g_pre_comp[i][booth - <span class="hljs-number">1</span>]);
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (booth &lt; <span class="hljs-number">0</span>) {
                sm2_point_sub_affine(R, R, &amp;g_pre_comp[i][-booth - <span class="hljs-number">1</span>]);
            }
        }
    }
    <span class="hljs-keyword">if</span> (R_infinity) {
        sm2_set_point_infi(R);
    }
}
</code></pre>
<h4 id="383-实验">3.8.3 实验</h4>
<p><strong>1. 5-NAF法签名耗时：1.77ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\5-naf_test_1.png" alt="5-naf"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\5-naf_test_2.png" alt="5-naf"></p>
<p><strong>2. 滑动窗口法签名耗时: 1.839ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\slide-window_1.png" alt="slide-window"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\slide-window_2.png" alt="slide-window"></p>
<p><strong>3. 窗口为7的预计算算法签名耗时: 0.256ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-7_1.png" alt="windows-7"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-7_2.png" alt="windows-7"></p>
<p><strong>4. 窗口为5的预计算算法签名耗时: 0.341ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-5_1.png" alt="window-5"></p>
<p><strong>5. 窗口为3的预计算算法签名耗时: 0.501ms</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\window-3_1.png" alt="window-3"></p>
<h4 id="384-结论">3.8.4 结论</h4>
<p>从实验可以看出，5-NAF比国标上的滑动窗口法速度略有提升；而使用了预计算的方法，签名速度是滑动窗口法的7倍，并且窗口越小，速度会下降。</p>
<h2 id="4-crypto栈集成方案">4. Crypto栈集成方案</h2>
<p>Crypto包含Crypto Service Manager（Csm）， Crypto Interface（CryIf）， Crypto Driver（Crypto）和Key Manager（KeyM）。</p>
<p>本小组分别对Crypto、CryIf和Csm模块自底向上进行配置，成功将SM2实现代码栈融合到小满操作系统Crypto栈中，符合AUTOSAR标准。</p>
<p>Crypto 栈各组件 Csm, CryIf 以及 Crypto 之间驱动和原语调度关系，以及密钥配置对应关系如下图所示</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\autosar_crypto_stack.png" alt="crypto"></p>
<h3 id="具体调用方案">具体调用方案</h3>
<ul>
<li>
<p>Csm 配置Job参数，包括mode、inputPtr、inputLenth、outputPtr、outputLenthPtr等。</p>
</li>
<li>
<p>CryptoInterface 根据配置的参数,如service、CtyIfKeyId等调用配置好的函数指针（Crypto_ProcessJob_Name）指向的函数。</p>
</li>
<li>
<p>CRYPTO 根据Job的Primitive信息决定是否用队列处理同步/异步任务。根据JobPrimitiveInputOutput.mode确定驱动状态。根据JobPrimitive的Service、Algorithmfamily确定调用具体Crypto Driver</p>
</li>
<li>
<p>在<code>Os_Userinf.c</code>中，配置了Task并设置看门定时喂狗避免程序重启。</p>
</li>
<li>
<p>配置Task在<code>Task(OsTask_5ms)</code></p>
</li>
<li>
<p><code>main.c</code>中<code>main</code>函数调用<code>EcuM_Init</code>启动操作系统并启动调度序列，程序将由操作系统通过Task自动调度。</p>
</li>
</ul>
<p><strong>调用示意图如下：</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_invoke.png" alt="crypto_invoke"></p>
<p><strong>Os和Task相关配置</strong></p>
<p>为了使程序顺利运行，我们将操作系统和Task栈分配了较大空间</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\os_1.png" alt="os_1"></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\os_2.png" alt="os_2"></p>
<h3 id="crypto">Crypto</h3>
<p>在AUTOSAR加密协议中，Crypto用于配置加密原语，作为加密Job的最终处理模块。
本小组在Crypto栈中添加如下加密处理函数用于调用底层SM2算法实现。</p>
<p><strong>API接口清单</strong></p>
<table>
<thead>
<tr>
<th>函数名称</th>
<th>函数功能</th>
<th>函数原型位置</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Crypto_SM2_SignatureGenerate_Process()</code></td>
<td>用于处理SM2签名请求</td>
<td><code>Crypto.c</code></td>
</tr>
<tr>
<td><code>Crypto_SM2_SignatureVerify_Process()</code></td>
<td>用于处理SM2验签请求</td>
<td><code>Crypto.c</code></td>
</tr>
<tr>
<td><code>Crypto_SM3_Process()</code></td>
<td>调用SM2杂凑函数</td>
<td><code>Crypto.c</code></td>
</tr>
<tr>
<td><code>Crypto_KeyGenerate()</code></td>
<td>用于公私钥生成，通过扩写SM2 CryptoKeyId判断逻辑添加SM2公私钥生成功能</td>
<td><code>Crypto.c</code></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_SM2_SignatureGenerate_Process()</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_SM2_SignatureGenerate_Process</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2_SignatureGenerate_Process()</td>
</tr>
<tr>
<td>函数描述</td>
<td>根据当前Job的CryptoKey获取私钥的KeyElement;获取当前Job的输入即杂凑值和消息： <code>Z_A||message</code>字节串；调用sm2签名函数，将签名结果写入当前Job的输出指针。</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_SM2_SignatureVerify_Process()</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_SM2_SignatureVerify_Process</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2_SignatureVerify_Process()</td>
</tr>
<tr>
<td>函数描述</td>
<td>根据当前Job的KeyId获取公钥的KeyElement;获取当前Job的输入即签名（r,s）、Z_A、message；调用sm2验签函数，将验签结果写入Job的Verify指针。</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_SM2EncryptProcess()</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_SM2EncryptProcess</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2EncryptProcess()</td>
</tr>
<tr>
<td>函数描述</td>
<td>根据当前Job的KeyId获取公钥的KeyElement;获取当前Job的输入，包括用于加密的公钥<code>pub_key</code>（32字节），待加密信息<code>input</code>（MaxLength=64 Bytes），待加密信息长度<code>inputLength</code></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_SM2DecryptProcess()</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_SM2DecryptProcess</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_SM2DecryptProcess()</td>
</tr>
<tr>
<td>函数描述</td>
<td>根据当前Job的KeyId获取公钥的KeyElement;获取当前Job的输入，包括用于解密的私钥<code>pri_key</code>（32字节），待解密信息，代解密信息的长度</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_KeyGenerate()</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_KeyGenerate</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_KeyGenerate(VAR(uint32, AUTOMATIC) cryptoKeyId)</td>
</tr>
<tr>
<td>函数描述</td>
<td>根据当前Job的KeyId获取公钥的KeyElement;获取当前Job的输入即签名（r,s）、Z_A、message；调用sm2验签函数，将验签结果写入Job的Verify指针。</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th><strong><code>Crypto_SM3_Process</code></strong></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>函数名称</td>
<td><code>Crypto_SM3_Process</code></td>
</tr>
<tr>
<td>函数原型</td>
<td>FUNC(Std_ReturnType, CRY_CODE) Crypto_SM3_Process()</td>
</tr>
<tr>
<td>函数描述</td>
<td>SM3_Process():获取Job的输入，调用sm3杂凑函数，将杂凑值写入Job的输出。</td>
</tr>
</tbody>
</table>
<p><strong>Crypto 在ORIENTAIS Configurator的配置如下：</strong></p>
<ul>
<li>
<p><strong>CryptoGeneral</strong>:</p>
<p>配置了一个Crypto Driver，设置CryptoInstanceId=0</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_general.png" alt="crypto"></p>
</li>
<li>
<p><strong>CryptoDriverObject</strong></p>
<p>配置了一个Crypto Driver Object，其中同六个Crypto Primitive绑定，包括SM2签名、验签、Hash函数和随机数生成，以及SM2加密和解密。设置CryptoDriverObjectId=0，队列大小CryptoQueueSize=10</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_driver_object.png" alt="crypto"></p>
</li>
<li>
<p><strong>CryptoKeyElements</strong></p>
<p>配置了两个CryptoKeyElements：<code>CryptoKeyElements_0</code>和<code>CryptoKeyElements_1</code>，其中前者用于签名公私钥生成相关的CryptoKeyElement以及用于生成加密解密公私钥生成的相关CryptoKeyelement。此处定义的A是加密的角色，B是解密的角色。后者则是用于简化验签公钥复制流程的CryptoKeyElement。</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_elements.png" alt="crypto"></p>
</li>
<li>
<p><strong>CryptoKeyTypes</strong></p>
<p>声明CryptoKey类型:</p>
<ul>
<li><code>CryptoKeyElement_SigGenPub</code>和<code>CryptoKeyElement_SigGenPrivate</code>绑定为<code>CryptoKey_Signature</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_sig.png" alt="crypto"></p>
<ul>
<li><code>CryptoKeyElement_Pub_Copy</code>绑定为<code>CryptoKeyType_Verify</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_verify.png" alt="crypto"></p>
<ul>
<li><code>CryptoKeyElement_Hash</code>绑定为<code>CryptoKeyType_Hash</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_hash.png" alt="crypto"></p>
<ul>
<li><code>CryptoKeyElement_Rand</code>绑定为<code>CryptoKeyType_Rand</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_rand.png" alt="crypto"></p>
<ul>
<li><code>CryptoKeyElement_Encrypt</code>绑定为<code>CryptoKeyType_Encrypt</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_encrypt.png" alt="crypto"></p>
<ul>
<li><code>CryptoKeyElement_decrypt</code>绑定为<code>CryptoKeyType_Decrypt</code>类型</li>
</ul>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\crypto_key_type_decrypt.png" alt="crypto"></p>
</li>
<li>
<p><strong>CryptoKeys</strong></p>
<p>所定义的CryptoKeys有六个，分别配置用于签名、验签、Hash、随机数、加密和解密的CryptoKey。</p>
<table>
<thead>
<tr>
<th>名称</th>
<th style="text-align:center">CryptoKeyId</th>
<th>CryptoKeyTypeRef</th>
</tr>
</thead>
<tbody>
<tr>
<td>CryptoKey_Signature</td>
<td style="text-align:center">0</td>
<td>CryptoKeyType_Signature</td>
</tr>
<tr>
<td>CryptoKey_Verify</td>
<td style="text-align:center">1</td>
<td>CryptoKeyType_Verify</td>
</tr>
<tr>
<td>CryptoKey_Hash</td>
<td style="text-align:center">2</td>
<td>CryptoKeyType_Hash</td>
</tr>
<tr>
<td>CryptoKey_Rand</td>
<td style="text-align:center">3</td>
<td>CryptoKeyType_Rand</td>
</tr>
<tr>
<td>CryptoKey_Encrypt</td>
<td style="text-align:center">4</td>
<td>CryptoKeyType_Encrypt</td>
</tr>
<tr>
<td>CryptoKey_Decrypt</td>
<td style="text-align:center">5</td>
<td>CryptoKeyType_Decrypt</td>
</tr>
</tbody>
</table>
</li>
<li>
<p><strong>CryptoPrimitives</strong><br>
定义了四个CryptoPrimitive，其中CryptoPrimitiveAlgorithmFamily目前选择的是<code>CRYPTO_ALGOFAM_CUSTOM</code>.<br>
具体定义如下：</p>
<ul>
<li>
<p>CryptoPrimitive_SM2_Signature</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_1.png" alt="crypto"></p>
</li>
<li>
<p>CryptoPrimitive_SM2_Verify</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_2.png" alt="crypto"></p>
</li>
<li>
<p>CryptoPrimitive_Hash</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_3.png" alt="crypto"></p>
</li>
<li>
<p>CryptoPrimitive_SM2_Rand</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_4.png" alt="crypto"></p>
</li>
<li>
<p>CryptoPrimitive_SM2_Encrypt</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_5.png" alt="crypto"></p>
</li>
<li>
<p>CryptoPrimitive_SM2_Decrypt</p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\primitive_6.png" alt="crypto"></p>
</li>
</ul>
</li>
</ul>
<h3 id="cryif">CryIf</h3>
<p>Crypto Interface(CryIf)模块介于底层Crypto Driver（Crypto）和上层Crypto Service Manager（Csm）之间。其对上层提供调用底层Crypto驱动接口，对下则对Crypto进行调用。
IMNB-SM2对CryIf的配置如下。</p>
<p><strong>CryIf 在ORIENTAIS Configurator的配置如下：</strong></p>
<ul>
<li>
<p><strong>CryIfIncludes</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_includes.png" alt="crypto_if"></p>
</li>
<li>
<p><strong>CryIfGeneral</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_general.png" alt="crypto_if"></p>
</li>
<li>
<p><strong>CryIfChannel</strong></p>
<p><img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_channels.png" alt="crypto_if"></p>
</li>
<li>
<p><strong>CryIfKey</strong></p>
<ul>
<li>CryIfKey_Signature <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_signature.png" alt="crypto_if"></li>
<li>CryIfKey_Verify <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_verify.png" alt="crypto_if"></li>
<li>CryIfKey_Hash <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_hash.png" alt="crypto_if"></li>
<li>CryIfKey_Rand <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_rand.png" alt="crypto_if"></li>
<li>CryIfKey_Encrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_encrypt.png" alt="crypto_if"></li>
<li>CryIfKey_Decrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\cryif_key_decrypt.png" alt="crypto_if"></li>
</ul>
</li>
</ul>
<h3 id="csm">Csm</h3>
<p>Csm提供同步或异步服务，其为软件层提供一个标准化接口访问密码调用相关功能，如加密解密签名验签等等。</p>
<p>在Csm中，包括一下重要的组件：</p>
<ul>
<li>Csm-Cbk: 包含CSM供上层调用的API函数的声明。</li>
<li>Csm_Internal.h: 包含CSM内部的变量和数据结构体的定义。</li>
<li>Csm_MemMap.h: CSM编译抽象文件。</li>
<li>Csm.c: CSM模块源文件，包含了API函数的实现。</li>
<li>Csm.h: CSM模块头文件，包含了API函数的扩展声明并定义了配置的数据结构体。</li>
</ul>
<p><strong>Csm 在ORIENTAIS Configurator的配置如下：</strong></p>
<ul>
<li><strong>CsmGeneral</strong><br>
<img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_general.png" alt="csm"></li>
<li><strong>CsmJobs</strong>：在Csm中配置了四种Job，包括签名，验证，求散列和随机数任务。
<ul>
<li>CsmJobs_Signature <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_signature.png" alt="csm"></li>
<li>CsmJobs_Verify <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_verify.png" alt="csm"></li>
<li>CsmJobs_Hash <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_hash.png" alt="csm"></li>
<li>CsmJobs_Rand <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_rand.png" alt="csm"></li>
<li>CsmJobs_Encrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_encrypt.png" alt="csm"></li>
<li>CsmJobs_Decrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_job_decrypt.png" alt="csm"></li>
</ul>
</li>
<li><strong>CsmKeys</strong>
<ul>
<li>CsmKeys_Signature <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_signature.png" alt="csm"></li>
<li>CsmKeys_Verify <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_verify.png" alt="csm"></li>
<li>CsmKeys_Hash <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_hash.png" alt="csm"></li>
<li>CsmKeys_Rand <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_rand.png" alt="csm"></li>
<li>CsmKeys_Encrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_encrypt.png" alt="csm"></li>
<li>CsmKeys_Decrypt <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_key_decrypt.png" alt="csm"></li>
</ul>
</li>
<li><strong>CsmPrimitives</strong>：在CsmPrimitives中配置了1个原语类CsmPrimitives_0，其内部配置了5个原语，包括CsmHashs，CsmJobKeyGenerates，CsmRandomGenerates，CsmSignatureGenerates，CsmSignatureVerifys， CsmEncrypts，CsmDecrypts
<img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_primitives.png" alt="csm">
<ul>
<li>CsmHashs
<ul>
<li>CsmSM3Config <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_sm3_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmJobKeyGenerates
<ul>
<li>CsmJobKeyGenerateConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_keygen_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmJobRandomGenerates
<ul>
<li>CsmJobRandomGenerateConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_randgen_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmJobSignatureGenerates
<ul>
<li>CsmJobSignatureGenerateConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_siggen_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmSignatureVerifys
<ul>
<li>CsmSignatureVerifyConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_sigver_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmEncrypts
<ul>
<li>CsmEncryptConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_enc_config.png" alt="csm"></li>
</ul>
</li>
<li>CsmDecrypts
<ul>
<li>CsmDecryptConfig <br/> <img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_dec_config.png" alt="csm"></li>
</ul>
</li>
</ul>
</li>
<li><strong>CsmQueues</strong><br>
<img src="file:///c:\Users\admin\WorkSpace-IMNB\000005\XMenFinals\IMNB-决赛作品-SM2算法集成文档\static\csm_queues.png" alt="csm"></li>
</ul>
<h2 id="5-测试与验证">5. 测试与验证</h2>
<p>我们在AMD Ryzen 9 7940HS(RDNA 3架构)以Host作为单核的虚拟机上对实现代码进行了签名验签测试，并针对主流的加密库算法(GmSSL和OpenSSL)进行了性能对比。
在不开启性能优化并以32位编译的情况下，我们通过计算三种SM2实现的平均签名验签速度进行测试。结果如下：</p>
<table>
<thead>
<tr>
<th></th>
<th style="text-align:center"></th>
<th style="text-align:center"></th>
<th style="text-align:center"></th>
</tr>
</thead>
<tbody>
<tr>
<td>项目名称</td>
<td style="text-align:center">OpenSSL-3.4.0（-m32，-bn(64, 32)，未开启优化）</td>
<td style="text-align:center">GmSSL (-m32, 未开启优化)</td>
<td style="text-align:center">IMNB（-m32, 未开启优化）</td>
</tr>
<tr>
<td>签名平均耗时（单位：ms）</td>
<td style="text-align:center">0.7</td>
<td style="text-align:center">0.287</td>
<td style="text-align:center">0.45</td>
</tr>
<tr>
<td>验签平均耗时（单位：ms）</td>
<td style="text-align:center">0.5</td>
<td style="text-align:center">N/A</td>
<td style="text-align:center">1.75</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th></th>
<th style="text-align:center"></th>
<th style="text-align:center"></th>
<th style="text-align:center"></th>
</tr>
</thead>
<tbody>
<tr>
<td>项目名称</td>
<td style="text-align:center">OpenSSL（-m32，-bn(64, 32)，开启-O3优化）</td>
<td style="text-align:center">GmSSL (-m32, 开启-O3优化)</td>
<td style="text-align:center">IMNB（-m32, 开启-O3优化, -fno-strict-aliasing）</td>
</tr>
<tr>
<td>签名平均耗时（单位：ms）</td>
<td style="text-align:center">0.5</td>
<td style="text-align:center">0.104</td>
<td style="text-align:center">0.126</td>
</tr>
<tr>
<td>验签平均耗时（单位：ms）</td>
<td style="text-align:center">0.4</td>
<td style="text-align:center">N/A</td>
<td style="text-align:center">0.787</td>
</tr>
</tbody>
</table>
<p>在ECC中，模逆操作是一个非常重要的操作，但是其计算代价较高，因此本小组实现了多种模逆算法，并对它们性能做出了比较，结果如下：</p>
<table>
<thead>
<tr>
<th>模逆算法</th>
<th style="text-align:center">消耗时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>fast_mod_p_inv</td>
<td style="text-align:center">0.089000ms</td>
</tr>
<tr>
<td>gcd_mod_p_inv</td>
<td style="text-align:center">0.009000ms</td>
</tr>
<tr>
<td>mont_mod_n_inv</td>
<td style="text-align:center">0.171000ms</td>
</tr>
<tr>
<td>gcd_mod_n_inv</td>
<td style="text-align:center">0.008000ms</td>
</tr>
</tbody>
</table>
<p>在ECC中，椭圆曲线基点标量乘法也是常用算法，因此，本小组对多种标量乘法进行了实现，包括通用标量乘法以及针对基点的标量乘法，将其融入到签名算法中，并对签名性能做出了比较，结果如下：</p>
<table>
<thead>
<tr>
<th>标量乘法</th>
<th style="text-align:center">消耗时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>5-NAF</td>
<td style="text-align:center">1.77ms</td>
</tr>
<tr>
<td>滑动窗口法</td>
<td style="text-align:center">1.839ms</td>
</tr>
<tr>
<td>窗口为7的预计算算法签名耗时</td>
<td style="text-align:center">0.256ms</td>
</tr>
<tr>
<td>窗口为5的预计算算法签名耗时</td>
<td style="text-align:center">0.341ms</td>
</tr>
<tr>
<td>窗口为3的预计算算法签名耗时</td>
<td style="text-align:center">0.501ms</td>
</tr>
</tbody>
</table>
<p>结论，针对通用算法，5-NAF会快于国标提到的滑动窗口法；而使用预计算方法，签名速度是滑动窗口若干倍（7倍以上），且窗口越小，速度下降。</p>
<p><strong>注：测试结果仅供参考</strong></p>
<h2 id="6-使用场景">6. 使用场景</h2>
<p>安全性挑战与场景分析</p>
<p>在汽车操作系统中，安全性是至关重要的，尤其是在涉及加密算法如SM2的实现中。以下是我们在安全性方面面临的主要挑战及其应对策略：</p>
<p>防止侧信道攻击：
挑战：侧信道攻击（如时间分析、功耗分析等）可以通过监测算法执行过程中的物理特征，推测出敏感信息（如私钥）。传统的GCD算法（如欧几里得算法）由于其依赖于输入数据的特定模式和执行路径，容易受到时间分析攻击。
应对策略：我们采用了safegcd算法，这是一种安全的最大公约数算法，旨在通过常数时间执行和最小化分支操作，防止攻击者通过分析执行时间和操作模式来获取敏感信息。safegcd通过以下方式增强安全性：
常数时间执行：确保算法的执行时间与输入数据无关，避免因时间差异泄露信息。
减少分支和条件跳转：通过优化算法逻辑，降低代码中的条件判断和分支操作，减少预测失败和分支跳转带来的执行路径差异。
优化数学运算：采用高效的位运算和大数运算优化，提升算法性能的同时，保持操作的一致性。</p>
<h2 id="参考文献">参考文献</h2>
<p>[1]	Chen, X.; Fu, Y. A Novel JSF-Based Fast Implementation Method for Multiple-Point Multiplication. Electronics 2023, 12, 3530. <a href="https://doi.org/10.3390/electronics12163530">https://doi.org/10.3390/electronics12163530</a><br>
[2]	Islam M M, Hossain M S, Hasan M K, et al. FPGA implementation of high-speed area-efficient processor for elliptic curve point multiplication over prime field[J]. IEEE Access, 2019, 7: 178811-178826.<br>
[3]	Khleborodov D. Fast elliptic curve point multiplication based on binary an- d binary non-adjacent scalar form methods[J]. Advances in Computational M-athematics, 2018, 44(4): 1275-1293.<br>
[4]	Solinas J A . Low-Weight Binary Representations for Pairs of Integers[J]. 2001.<br>
[5]	Wang W, Fan S. Attacking OpenSSL ECDSA with a small amount of side- channel information[J]. Science China Information Sciences, 2018, 61: 1-14.<br>
[6]	Koyama K, Tsuruoka Y. Speeding up elliptic cryptosystems by using a sig ned binary window method[C]//Annual International Cryptology Conference. Berlin, Heidelberg: Springer Berlin Heidelberg, 1992: 345-357.<br>
[7]	Brickell E F, Gordon D M, McCurley K S, et al. Fast exponentiation with precomputation[C]//Workshop on the Theory and Application of of Crypto g-raphic Techniques. Berlin, Heidelberg: Springer Berlin Heidelberg, 1992: 200-207.<br>
[8]	李学俊,胡磊.一种适合椭圆曲线密码的快速标量乘法对算法[C]//中国密码学 学术会议.上海交通大学, 2004.<br>
[9] Bernstein D J, Yang B Y. Fast constant-time gcd computation and modular inversion[J]. IACR Transactions on Cryptographic Hardware and Embedded Systems, 2019: 340-398.<br>
[10] Z. Zhao and G. Bai, &quot;Ultra High-Speed SM2 ASIC Implementation,&quot; <em>2014 IEEE 13th International Conference on Trust, Security and Privacy in Computing and Communications</em>, Beijing, China, 2014, pp. 182-188, doi: 10.1109/TrustCom.2014.27.<br>
[11] Montgomery, P. L. (1985). &quot;Speeding the Pollard and Elliptic Curve Methods of Factorization&quot;. <em>Mathematics of Computation</em>, 48(177), 117-133</p>

            <script async src="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.js"></script>
            
        </body>
        </html>